Pthreads & Concurrency
Acknowledgements The material in this tutorial is based in part on: POSIX Threads Programming, by Blaise Barney
History Advantages Content
History Different versions of threads each hardware vendor created own version IEEE POSIX c Standard C programming types and procedure calls
Advantages Potential program performance gains Platform fork()pthread_create() realusersysrealusersys AMD 2.4 GHz Opteron IBM 1.9 GHz POWER5 p IBM 1.5 GHz POWER INTEL 2.4 GHz Xeon
Advantages More efficient inter-thread communication Threaded applications Overlap CPU work and I/O Priority/Real-time scheduling Asynchronous event handling
The Pthreads API Thread management Create, detach, join Set/query thread attributes Mutex Mutual Exclusion Condition variables Address communications between threads Non-mutex synchronization Read/write locks Barriers
The Pthreads API Naming conventions Routine PrefixFunctional Group pthread_Thread themselves and miscellaneous subroutines pthread_attr_Thread attributes objects pthread_mutex_Mutexes pthread_mutexattr_Mutex attributes objects pthread_cond_Condition variables pthread_condattr_Condition attributes objects pthread_key_Thread-specific data keys
Create & Terminate Program: Hello World
Creation Routine pthread_create( thread, attr, start_routine, arg)
Termination Four ways for a Pthread to terminate Returns from start_routine Call pthread_exit routine Cancel by another thread through pthread_cancel routine exit call
Example: Hello World Program Requirements Print “Hello World” through standard output Use two threads to finish the task, one should print “Hello”, the other should print “World” Terminate all related threads related after finishing the printing task
Example: Hello World #include ……
Example: Hello World void print_message_function( void *ptr ) { char *message; message = (char *) ptr; printf("%s ", message); }
Example: Hello World main() { pthread_t thread1, thread2; char *message1 = "Hello"; char *message2 = "World"; …… }
Example: Hello World main() { pthread_t thread1, thread2; char *message1 = "Hello"; char *message2 = "World"; …… }
Example: Hello World main() { pthread_t thread1, thread2; char *message1 = "Hello"; char *message2 = "World"; …… }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World main() { …… pthread_create(&thread1, pthread_attr_default, (void*)&print_message_function, (void*) message1); pthread_create(&thread2, pthread_attr_default, (void*)&print_message_function, (void*) message2); exit(0); }
Example: Hello World default threadThread 2Thread 1
Example: Hello World default threadThread 2Thread 1
Example: Hello World default threadThread 2Thread 1
Example: Hello World default threadThread 2Thread 1
Example: Hello World default threadThread 2Thread 1
Example: Hello World default threadThread 2Thread 1 Printf
Example: Hello World default threadThread 2Thread 1 PrintfExitPrintf
Example: Hello World Thread 1Thread 2 standard output Thread 1 default thread Thread 2 Return
Example: Hello World void print_message_function( void *ptr ) { char *message; message = (char *) ptr; printf("%s ", message); } main() { …… pthread_exit(); //exit(0); }
Example: Hello World void print_message_function( void *ptr ) { char *message; message = (char *) ptr; printf("%s ", message); pthread_exit(); } main() { …… pthread_exit(); //exit(0); }
Passing parameters to threads The pthread_create() routine permits the programmer to pass one argument to the thread start routine. For cases where multiple arguments must be passed, this limitation is overcome by creating a structure which contains all of the arguments, and then passing a pointer to that structure. All arguments must be passed by reference and cast to (void *).
Joining and detaching threads pthread_join (threadid,status) blocks the calling thread until the specified threadid thread terminates. target thread's termination return status placed in status if specified in the target thread's call to pthread_exit(). A joining thread can match one pthread_join() call. It is a logical error to attempt multiple joins on the same thread. pthread_detach (threadid, status) to explicitly detach a thread pthread_attr_setdetachstate (attr,detachstate) pthread_attr_getdetachstate (attr, detachstate)
Create & Destroy Lock & Unlock Program: Bounded Buffer
Mutex Mutual Exclusion Act as a “lock” to prevent race conditions Typical sequence of use create, initialize lock, unlock destroy Losers in the competition for the mutex variable have to block
Creating & Destroying Type: pthread_mutex_t Initializing Statically ○ pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER Dynamically ○ pthread_mutex_init (mutex, attr) pthread_mutex_attr_t attr specifies protocol for priorities, priority ceiling, and process sharing Destroying pthread_mutex_destroy – to delete a mutex object pthread_mutex_attr_destroy – to delete a mutex attr object
Lock & Unlock Lock pthread_mutex_lock (mutex) ○ blocks calling thread if mutex already locked pthread_mutex_trylock(mutex) ○ returns with “busy” code if already locked Unlock pthread_mutex_unlock (mutex) Error ○ mutex is released ○ mutex owned by others