35
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

Pthread (continue)

  • Upload
    charla

  • View
    57

  • Download
    0

Embed Size (px)

DESCRIPTION

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 - PowerPoint PPT Presentation

Citation preview

Page 1: Pthread (continue)

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

Page 2: Pthread (continue)

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!

Page 3: Pthread (continue)

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

Page 4: Pthread (continue)

Motivating Example: Too Much Milk

Dumb4:00 Look into fridge:

Out of milk

Dumber

Page 5: Pthread (continue)

Motivating Example: Too Much Milk

Dumb4:00 Look into fridge:

Out of milk4:05 Head for the

warehouse

Dumber

Page 6: Pthread (continue)

Motivating Example: Too Much Milk

Dumb4:05 Head for the

warehouse

Dumber

4:10 Look into fridge: Out of milk

Page 7: Pthread (continue)

Motivating Example: Too Much Milk

Dumb Dumber4:10 Look into fridge:

Out of milk4:15 Head for the

warehouse

Page 8: Pthread (continue)

Motivating Example: Too Much Milk

Dumb

4:20 Arrive with milk

Dumber4:15 Head for the

warehouse

Page 9: Pthread (continue)

Motivating Example: Too Much Milk

Dumb

4:20 Arrive with milk

Dumber4:15 Head for the

warehouse

Page 10: Pthread (continue)

Motivating Example: Too Much Milk

Dumb4:20 Arrive with milk4:25 Go party

Dumber

Page 11: Pthread (continue)

Motivating Example: Too Much Milk

Dumb4:20 Arrive with milk4:25 Go party

Dumber

4:30 Arrive with milk: “Uh oh…”

Page 12: Pthread (continue)

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.

Page 13: Pthread (continue)

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… ...

Page 14: Pthread (continue)

Pthreads synchronization support

• Mutex locks– Critical session and mutual exclusion

• Condition variables– Event synchronization

• Semaphores– Both (in UNIX, not pthread)

Page 15: Pthread (continue)

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

Page 16: Pthread (continue)

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.

Page 17: Pthread (continue)

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

Page 18: Pthread (continue)

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;}

Page 19: Pthread (continue)

Mutex exampleint 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;}

Page 20: Pthread (continue)

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

Page 21: Pthread (continue)

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.

Page 22: Pthread (continue)

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

Page 23: Pthread (continue)

Producer consumer program without condition variables

Page 24: Pthread (continue)

/* 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);

}

Page 25: Pthread (continue)

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();}

Page 26: Pthread (continue)

Producer consumer with condition variables

Page 27: Pthread (continue)

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);

}

Page 28: Pthread (continue)

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();}

Page 29: Pthread (continue)

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.

Page 30: Pthread (continue)

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

Page 31: Pthread (continue)

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]); }

Page 32: Pthread (continue)

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

Page 33: Pthread (continue)

Deadlock example

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

Page 34: Pthread (continue)

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.

Page 35: Pthread (continue)

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