Threads Programming Thread creation Synchronization.

Slides:



Advertisements
Similar presentations
Threads. Readings r Silberschatz et al : Chapter 4.
Advertisements

Pthreads & Concurrency. Acknowledgements  The material in this tutorial is based in part on: POSIX Threads Programming, by Blaise Barney.
Multi-core Programming Programming with Posix Threads.
PTHREADS These notes are from LLNL Pthreads Tutorial
Threads Lab اللهم علمنا ما ينفعنا،،، وانفعنا بما علمتنا،،، وزدنا علماً
Lecture 12 Overview. UDP Connected mode A UDP socket can be used in a call to connect() This simply tells the O.S. the address of the peer No handshake.
Computer Architecture II 1 Computer architecture II Programming: POSIX Threads OpenMP.
Fork Fork is used to create a child process. Most network servers under Unix are written this way Concurrent server: parent accepts the connection, forks.
8-1 JMH Associates © 2004, All rights reserved Windows Application Development Chapter 10 - Supplement Introduction to Pthreads for Application Portability.
Lecture 18 Threaded Programming CPE 401 / 601 Computer Network Systems slides are modified from Dave Hollinger.
Threads© Dr. Ayman Abdel-Hamid, CS4254 Spring CS4254 Computer Network Architecture and Programming Dr. Ayman A. Abdel-Hamid Computer Science Department.
Pthread II. Outline Join Mutex Variables Condition Variables.
Netprog Threads Programming1 Threads Programming Refs: Chapter 23.
Introduction to Pthreads. Pthreads Pthreads is a POSIX standard for describing a thread model, it specifies the API and the semantics of the calls. Model.
PRINCIPLES OF OPERATING SYSTEMS Lecture 6: Processes CPSC 457, Spring 2015 May 21, 2015 M. Reza Zakerinasab Department of Computer Science, University.
10/16/ Realizing Concurrency using the thread model B. Ramamurthy.
Programming with TCP – III 1. Zombie Processes 2. Cleaning Zombie Processes 3. Concurrent Servers Using Threads  pthread Library Functions 4. TCP Socket.
Today’s topic Pthread Some materials and figures are obtained from the POSIX threads Programming tutorial at
June-Hyun, Moon Computer Communications LAB., Kwangwoon University Chapter 26 - Threads.
Multi-threaded Programming with POSIX Threads CSE331 Operating Systems Design.
Threads and Thread Control Thread Concepts Pthread Creation and Termination Pthread synchronization Threads and Signals.
CS345 Operating Systems Threads Assignment 3. Process vs. Thread process: an address space with 1 or more threads executing within that address space,
Programming with POSIX* Threads Intel Software College.
ECE 297 Concurrent Servers Process, fork & threads ECE 297.
Professor: Shu-Ching Chen TA: Samira Pouyanfar.  An independent stream of instructions that can be scheduled to run  A path of execution int a, b; int.
Pthreads: A shared memory programming model
Threads CSCE Thread Motivation Processes are expensive to create. Context switch between processes is expensive Communication between processes.
S -1 Posix Threads. S -2 Thread Concepts Threads are "lightweight processes" –10 to 100 times faster than fork() Threads share: –process instructions,
Threads and Locking Ioctl operations. Threads Lightweight processes What’s wrong with processes? –fork() is expensive – 10 to 100 times slower –Inter.
Threads Chapter 26. Threads Light-weight processes Each process can have multiple threads of concurrent control. What’s wrong with processes? fork() is.
1 Pthread Programming CIS450 Winter 2003 Professor Jinhua Guo.
POSIX Synchronization Introduction to Operating Systems: Discussion Module 5.
POSIX Threads HUJI Spring 2011.
Pthreads.
Pthreads #include pthread_t tid ; //thread id. pthread_attr_t attr ; void *sleeping(void *); /* thread routine */ main() { int time = 2 ; pthread_create(&tid,
Operating Systems ECE344 Ashvin Goel ECE University of Toronto Unix System Calls and Posix Threads.
12/22/ Thread Model for Realizing Concurrency B. Ramamurthy.
Chapter 6 P-Threads. Names The naming convention for a method/function/operation is: – pthread_thing_operation(..) – Where thing is the object used (such.
Unix Internals Concurrent Programming. Unix Processes Processes contain information about program resources and program execution state, including: Process.
Page 1 threads CS 360, WSU Vancouver POSIX Threads 1. Background 2. Threads vs. Processes 3. Thread Synchronization 4. Mutex Variables 5. Condition Variables.
PThread Synchronization. Thread Mechanisms Birrell identifies four mechanisms commonly used in threading systems –Thread creation –Mutual exclusion (mutex)
Thread S04, Recitation, Section A Thread Memory Model Thread Interfaces (System Calls) Thread Safety (Pitfalls of Using Thread) Racing Semaphore.
Thread Basic Thread operations include thread creation, termination, synchronization, data management Threads in the same process share:  Process address.
Working with Pthreads. Operations on Threads int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void * (*routine)(void*), void* arg) Creates.
pThread synchronization
7/9/ Realizing Concurrency using Posix Threads (pthreads) B. Ramamurthy.
Case Study: Pthread Synchronization Dr. Yingwu Zhu.
Tutorial 4. In this tutorial session we’ll see Threads.
Principles of Operating Systems Lecture 11
Fork VS. Threads Lab 05.
Shared-Memory Programming with Threads
Threads Threads.
Netprog: Threads Programming
Copyright ©: Nahrstedt, Angrave, Abdelzaher
Thread Programming.
PTHREADS These notes are from LLNL Pthreads Tutorial
Multithreading Tutorial
POSIX Threads 1. Background 2. Threads vs. Processes
Realizing Concurrency using Posix Threads (pthreads)
Chapter 5 (part 1) TCP Client /Server Example By: Lim Meng Hui.
Realizing Concurrency using the thread model
Multithreading Tutorial
Thread Programming.
Pthread Prof. Ikjun Yeom TA – Mugyo
Multithreading Tutorial
Multithreading Tutorial
Realizing Concurrency using Posix Threads (pthreads)
Realizing Concurrency using the thread model
Realizing Concurrency using Posix Threads (pthreads)
POSIX Threads(pthreads)
Presentation transcript:

Threads Programming Thread creation Synchronization

Threads vs. Processes Creation of a new process using fork is expensive (time & memory). IPC is required to pass information between parent and child –A thread (sometimes called a lightweight process) does not require lots of memory or startup time. –It shares memory with parent, no IPC is required

fork() Process A Global Variables Code Stack Process B Global Variables Code Stack

pthread_create() Process A Thread 1 Global Variables Code Stack Process A Thread 2 Stack pthread_create()

Thread Programming Share heap, data, text segments, global variables, file descriptors, CWD, user, group ids, signal handlers, signal dispositions Individual stack, registers, program counters, errno, signal mask, priority

Introduction to Thread Programming Advantages of using threads  Increased efficiency  Shared memory (efficient communication) easier for monitor and control (e.g. statistics collection) Disadvantages of using threads  Synchronization overhead  Many library functions are not thread-safe (e.g., gethostbyname)

Thread Programming API Thread Management  creation, detach, join, exit  POSIX requires all threads are created as joinable threads Thread Synchronization  join  mutex (i.e. semapore with value of 1)  semaphore  condition variables

Client using threads

Client.c void *copyto (void *); static int sockfd; /* global for both threads to access */ static FILE *fp; void str_cli(FILE *fp_arg, int sockfd_arg) { char recvline[MAXLINE]; pthread_t tid; sockfd = sockfd_arg; /* copy arguments to externals */ fp = fp_arg; Pthread_create(&tid, NULL, copyto, NULL); while (Readline(sockfd, recvline, MAXLINE) > 0) Fputs(recvline, stdout); } void * copyto(void *arg) { char sendline[MAXLINE]; while (Fgets(sendline, MAXLINE, fp) ! = NULL) Writen(sockfd, sendline, strlen(sendline)); Shutdown(sockfd, SHUT_WR); /* EOF on stdin, send FIN */ return (NULL); /* return (i.e., thread terminates) when EOF on stdin */ }

int main(int argc, char **argv) { int listenfd, *iptr; thread_t tid; socklen_t addrlen, len; struct sockaddr *cliaddr; listenfd = Tcp_listen(argv[1], argv[2], &addrlen); cliaddr = Malloc(addrlen); for ( ; ; ) { len = addrlen; iptr = Malloc(sizeof(int)); *iptr = Accept(listenfd, cliaddr, &len); Pthread_create(&tid, NULL, &doit, iptr); } TCP Echo Server using Threads static void * doit(void *arg) { int connfd; connfd = *((int *) arg); free(arg); Pthread_detach(pthread_self()); str_echo(confd); /* same function as before */ Close(confd); /* done with connected socket */ return (NULL); }

Thread Creation initializes its attributes using the thread attributes object specified by the attr parameter thread attribues:  priority, stack size, name, detach-state, etc. start executing start_routine, with the parameter arg #include int pthread_create (pthread_t *thread, const pthread_attr_t *attr, void*(*start_routine) (void *), void *arg)

pthread_create() The return value is 0 for OK. Positive error number on error. Does not set errno !!! Thread ID is returned in tid

Thread Creation Each thread has a unique ID, a thread can find out it's ID by calling pthread_self(). Thread IDs are of type pthread_t which is usually an unsigned int. When debugging, it's often useful to do something like this: printf("Thread %u:\n",pthread_self()); When func() is called the value arg specified in the call to pthread_create() is passed as a parameter. func can have only 1 parameter, and it can't be larger than the size of a void *.

Thread Creation Complex parameters can be passed by creating a structure and passing the address of the structure. The structure can't be a local variable (of the function calling pthread_create)!!  threads have different stacks!

Thread Lifecycle – joinable thread similar to waitpid(), calling thread blocks Thread Termination 1.returns from its starting routing (main program) 2.call pthread_exit 3.cancelled by another thread pthread_cancel 4.process terminated status returned thread attributes specified

pthread_join Wait for a given thread to terminate by calling pthread_join.  similar to waitpid. #include int pthread_join (pthread_t tid, void ** status);

Thread Detach A thread can be changed to detached state A detached thread releases all its resource when it terminates A detached thread cannot be joined Example  pthread_detach(pthread_self()) #include int pthread_detach (pthread_t tid)

Thread-safe Functions Two of the functions are thread-safe only if the caller allocates space for the result and passes that pointer as the argument to the function.  inet_pton() //thread safe  gethostbyname() //not thread safe

Synchronization Problem #define NLOOP 5000 int counter; /* incremented by threads */ void *doit(void *); int main(int argc, char **argv) { pthread_t tidA, tidB; Pthread_create(&tidA, NULL, &doit, NULL); Pthread_create(&tidB, NULL, &doit, NULL); /* wait for both threads to terminate */ Pthread_join(tidA, NULL); Pthread_join(tidB, NULL); exit(0); } void * doit(void *vptr) { int i, val; /* * Each thread fetches, prints, and increments the counter NLOOP times. * The value of the counter should increase monotonically. */ for (i = 0; i < NLOOP; i++) { val = counter; printf("%d: %d\n", pthread_self(), val + 1); counter = val + 1; } return (NULL); }

Output

Mutex Variables Protects access to shared data resources A typical sequence  Create and initialize a mutex variable  Several threads attempt to lock the mutex  Only one succeeds and that thread owns the mutex  The owner thread performs some set of actions  The owner unlocks the mutex  Another thread acquires the mutex and repeats the process  Finally the mutex is destroyed

Mutex Variables #define NLOOP 5000 int counter; /* incremented by threads */ pthread_mutex_t counter_mutex = PTHREAD_MUTEX_INITIALIZER; void *doit(void *); int main(int argc, char **argv) { pthread_t tidA, tidB; Pthread_create(&tidA, NULL, &doit, NULL); Pthread_create(&tidB, NULL, &doit, NULL); /* wait for both threads to terminate */ Pthread_join(tidA, NULL); Pthread_join(tidB, NULL); exit(0); } void * doit(void *vptr) { int i, val; /* * Each thread fetches, prints, and increments the counter NLOOP times. * The value of the counter should increase monotonically. */ for (i = 0; i < NLOOP; i++) { Pthread_mutex_lock(&counter_mutex); val = counter; printf("%d: %d\n", pthread_self(), val + 1); counter = val + 1; Pthread_mutex_unlock(&counter_mutex); } return (NULL); }

Lock / Unlock Mutexes pthread_mutex_lock() is used to acquire a lock on the mutex variable. If the mutex variable is already locked, then the thread will block. pthread_mutex_trylock() is used to acquire a lock on the mutex variable. If the mutex variable is locked, then the thread will NOT block. pthread_mutex_unlock() will unlock the mutex variable if called by the owning thread. #include int pthread_mutex_lock (pthread_mutex_t *mutex); int pthread_mutex_trylock (pthread_mutex_t *mutex); Int pthread_mutex_unlock (pthread_mutex_t *mutex);

Condition Variables pthreads support condition variables, which allow one thread to wait (sleep) for an event generated by any other thread. This allows us to avoid the busy waiting problem.  Mutex variables prevent simultaneous access to a shared variable  Condition variables allow threads to synchronize on the actual value of a shared variable Without condition variables, the programmer would need to have threads continually polling to check if the condition is met. A condition variable is always used in conjunction with a mutex lock

Busy Waiting Problem active_threads=0; // start up n threads on first n clients // make sure they are all running while (1) { // have to lock/release active_threads if (active_threads < n) //busy waiting // start up thread for next client }

Condition Variables (cont.) A condition variable is always used with mutex.  pthread_cond_wait(pthread_cond_t *cptr,  pthread_mutex_t *mptr);  pthread_cond_signal(pthread_cond_t *cptr); don’t let the word signal confuse you - this has nothing to do with Unix signals

Each thread decrements active_threads when terminating and calls pthread_cond_signal to wake up the main loop. The main thread increments active_threads when each thread is started and waits for changes by calling pthread_cond_wait. Condition Variables

All changes to active_threads must be inside the lock and release of a mutex. If two threads are ready to exit at (nearly) the same time – the second must wait until the main loop recognizes the first. We don’t lose any of the condition signals. Condition Variables

Global Variables // global variable the number of active // threads (clients) int active_threads=0; // mutex used to lock active_threads pthread_mutex_t at_mutex = PTHREAD_MUTEX_INITIALIZER; // condition var. used to signal changes pthread_cond_t at_cond = PTHREAD_COND_INITIALIZER;

Child Thread Code void *cld_func(void *arg) {... // handle the client... pthread_mutex_lock(&at_mutex); active_threads--; pthread_cond_signal(&at_cond); pthread_mutex_unlock(&at_mutex); return(); }

Main thread // no need to lock yet active_threads=0; while (1) { pthread_mutex_lock(&at_mutex); while (active_threads < n ) { active_threads++; pthread_create(…) } pthread_cond_wait( &at_cond, &at_mutex); pthread_mutex_unlock(&at_mutex); }

Typical Sequence of Condition Variables Main thread: Declare and initialize global data/variables which require synchronization (such as "count") Declare and initialize a condition variable object Declare and initialize an associated mutex Create threads A and B to do work

Thread A 1. Work up to the point where a certain condition must occur 2. Lock associated mutex mx and check value of a shared variable cv 3. Call pthread_cond_wait(cv,mx) to perform a blocking wait for signal from Thread-B. (Note: the blocking wait automatically and atomically unlocks the mutex mx ) 4. When signalled, wake up. Mutex mx is automatically and atomically locked. 5. Explicitly unlock mutex mx 6. Continue Thread B 1. Do work 2. Lock associated mutex mx Change the value of the shared variable cv that Thread-A is waiting upon. 3. Check value of the global Thread-A wait variable cv. If it fulfills the desired condition, signal Thread-A. 4. Unlock mutex mx. 5. Continue 1. Declare and initialize global data/variables which require synchronization (such as "count") 2. Declare and initialize a condition variable object 3. Declare and initialize an associated mutex 4. Create threads A and B to do work Typical Condition Variable Sequence MAIN THREAD

Waiting / Signaling on Condition Variables pthread_cond_wait() blocks the calling thread until the specified condition is satisfied. It should be called with mutex locked. pthread_cond_signal() is used to wake up another thread which is waiting on the condition. It should unlock mutex after calling pthread_cond_signal(). pthread_cond_broadcast() is used if there are more than one waiting threads. #include int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mutex); int pthread_cond_signal (pthread_cond_t *cond); Int pthread_cond_broadcast (pthread_cond_t *cond);