Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pthread (continue) General pthread program structure –Encapsulate parallel parts (can be almost the whole program) in functions. –Use function arguments.

Similar presentations


Presentation on theme: "Pthread (continue) General pthread program structure –Encapsulate parallel parts (can be almost the whole program) in functions. –Use function arguments."— Presentation transcript:

1 Pthread (continue) General pthread program structure –Encapsulate parallel parts (can be almost the whole program) in functions. –Use function arguments to parameterize what a particular thread does. Usually needs to know myid and nprocs. Add synchronization when necessary –Call pthread_create() with the function and arguments, save thread identifier returned. –Call pthread_join() with that thread identifier

2 Thread synchronizations When more than one thread works on the same task, the threads often need to coordinate their activities to ensure correct behavior. –Coordination that results in synchronization or communication is the inherent price to pay when going multithreading. Coordination often means waiting!

3 Motivating Example: Too Much Milk Two robots are programmed to maintain the milk inventory at a store… They are not aware of each other’s presence… Robot: Dumb Robot: Dumber

4 Motivating Example: Too Much Milk Dumb 4:00Look into fridge: Out of milk Dumber

5 Motivating Example: Too Much Milk Dumb 4:00Look into fridge: Out of milk 4:05Head for the warehouse Dumber

6 Motivating Example: Too Much Milk Dumb 4:05Head for the warehouse Dumber 4:10Look into fridge: Out of milk

7 Motivating Example: Too Much Milk DumbDumber 4:10Look into fridge: Out of milk 4:15 Head for the warehouse

8 Motivating Example: Too Much Milk Dumb 4:20Arrive with milk Dumber 4:15 Head for the warehouse

9 Motivating Example: Too Much Milk Dumb 4:20Arrive with milk Dumber 4:15 Head for the warehouse

10 Motivating Example: Too Much Milk Dumb 4:20Arrive with milk 4:25Go party Dumber

11 Motivating Example: Too Much Milk Dumb 4:20Arrive with milk 4:25Go party Dumber 4:30Arrive with milk: “Uh oh…”

12 Common coordination constructs Critical section: a piece of code that only one thread can execute at a time –Only one thread can go get milk at one time. Mutual exclusion: ensure one thread can do something without the interference of other threads –When I print, nobody else should be printing.

13 Common coordination constructs Synchronization: use atomic operations to ensure cooperation among threads –Event synchronization T1 T2 … X = 400 Y = X+1 …... T1 T2 … X = 400 …. X ready … wait for X Y=X+1 …...

14 Pthreads synchronization support Mutex locks –Critical session and mutual exclusion Condition variables –Event synchronization Semaphores –Both (in UNIX, not pthread)

15 Mutex locks: lock/unlock pthread_mutex_lock(pthread_mutex_t *mutex); –Tries to acquire the lock specified by mutex –If mutex is already locked, then the calling thread blocks until mutex is unlocked. At one time, only one thread can get the lock

16 Mutex locks: lock/unlock pthread_mutex_unlock(pthread_mutex_t *mutex); –If the calling thread has mutex currently locked, this will unlock the mutex. –If other threads are blocked waiting on this mutex, one will unblock and acquire mutex. –Which one is determined by the scheduler.

17 Lock and critical section A lock prevents a thread from doing something –A thread should lock before entering a critical section –A thread should unlock when leaving the critical section –A thread should wait if the critical section is locked Synchronization often involves waiting

18 Mutex lock– for mutual exclusion int counter = 0; void *thread_func(void *arg) { int val; /* unprotected code – why? */ val = counter; counter = val + 1; return NULL; }

19 Mutex example int counter = 0; ptread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *thread_func(void *arg) { int val; /* protected by mutex */ Pthread_mutex_lock( &mutex ); val = counter; counter = val + 1; Pthread_mutex_unlock( &mutex ); return NULL; }

20 Condition variables – and event synchronization Think of Producer – consumer problem Producers and consumers run in separate threads. Producer produces data and consumer consumes data. Producer has to inform the consumer when data is available Consumer has to inform producer when buffer space is available

21 Condition variables: wait Pthread_cond_wait(pthread_cond_t *cond, pthread_mutex_t *mutex) –Blocks the calling thread, waiting on cond. –Unlock the mutex –Re-acquires the mutex when unblocked.

22 Condition variables: signal Pthread_cond_signal(pthread_cond_t *cond) –Unblocks one thread waiting on cond. –The scheduler determines which thread to unblock. –If no thread waiting, then signal is a no-op

23 Producer consumer program without condition variables

24 /* Globals */ int data_avail = 0; pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER; void *producer(void *) { Pthread_mutex_lock(&data_mutex); Produce data Insert data into queue; data_avail=1; Pthread_mutex_unlock(&data_mutex); }

25 void *consumer(void *) { while( !data_avail ); /* do nothing – keep looping!!*/ Pthread_mutex_lock(&data_mutex); Extract data from queue; if (queue is empty) data_avail = 0; Pthread_mutex_unlock(&data_mutex); consume_data(); }

26 Producer consumer with condition variables

27 int data_avail = 0; pthread_mutex_t data_mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cont_t data_cond = PTHREAD_COND_INITIALIZER; void *producer(void *) { Pthread_mutex_lock(&data_mutex); Produce data Insert data into queue; data_avail = 1; Pthread_cond_signal(&data_cond); Pthread_mutex_unlock(&data_mutex); }

28 void *consumer(void *) { Pthread_mutex_lock(&data_mutex); while( !data_avail ) { /* sleep on condition variable*/ Pthread_cond_wait(&data_cond, &data_mutex); } /* woken up */ Extract data from queue; if (queue is empty) data_avail = 0; Pthread_mutex_unlock(&data_mutex); consume_data(); }

29 A note on condition variables A signal is forgotten if there is no corresponding wait that has already occurred. If you want the signal to be remembered, use semaphores.

30 Semaphores Counters for resources shared between threads. Sem_wait(sem_t *sem) –Blocks until the semaphore vale is non-zero –Decrements the semaphore value on return. Sem_post(sem_t *sem) –Unblocks the semaphore and unblocks one waiting thread –Increments the semaphore value otherwise

31 Pipelined task parallelism with semaphore P1: for (I=0; I<num_pics, read(in_pic); I++) { int_pic_1[I] = trans1(in_pic); sem_post(event_1_2[I]); } P2: for (I=0; I<num_pics; I++) { sem_wait(event_1_2[I]); int_pic_2[I] = trans2(int_pic_1[I]); sem_post(event_2_3[I]); }

32 Challenges with thread programming Race condition: occurs when multiple threads and write to the same memory location. –Solution with a coordination mechanism: lock, conditional variable, semaphore, etc Coordination results in waiting among threads –Deadlocks: occur when threads are waiting for resources with circular dependencies

33 Deadlock example T1: T2: … Lock(printer) lock(keyboard) … Lock (keyboard) lock(printer) … Unlock(keyboard) unlock(printer) … Unlock(printer) unlock(keyboard)

34 Deadlock and third party software In sequence programs, using third party software is trivial. –Call “system(“/usr/bin/ls”); –No knowledge about /usr/bin/ls is needed. Could deadlock happen in thread programming by calling a third party program? –This is a big problem facing multi-thread programming.

35 Summary What is thread coordination (synchronization)? Why? What are the common thread coordinations? Pthread’s support for thread coordination. –Mutex lock –Condition variable Deadlock Thread programming issues


Download ppt "Pthread (continue) General pthread program structure –Encapsulate parallel parts (can be almost the whole program) in functions. –Use function arguments."

Similar presentations


Ads by Google