180 likes | 314 Views
Computer architecture II. Programming: POSIX Threads OpenMP. POSIX Threads. Why threads?. All threads within a process share the same address space. Inter-thread communication is more efficient and easier to use than inter-process communication. performance gains
E N D
Computer architecture II Programming: POSIX Threads OpenMP Computer Architecture II
POSIX Threads Computer Architecture II
Why threads? • All threads within a process share the same address space. • Inter-thread communication is more efficient and easier to use than inter-process communication. • performance gains • Overlapping CPU work with I/O • I/O operation in one thread • Computation in another • Priority/real-time scheduling: tasks which are more important can be scheduled before lower priority tasks • Interleaving of tasks (Ex.: a web server can both transfer data from previous requests and manage the arrival of new requests.) • SMP architecture: is to achieve optimum performance • MPI for inter-node communications • Pthreads for on-node data transfer Computer Architecture II
Thread subroutines • Thread management: • thread creating, detaching, joining, etc. • functions to set/query thread attributes (joinable, scheduling etc.) • Mutexes: synchronization primitives ( "mutual exclusion“). • creating, destroying, locking and unlocking mutexes. • mutex attribute functions that set or modify attributes associated with mutexes. • Condition variables: communications between threads that share a mutex (based upon programmer specified conditions). • functions to create, destroy, wait and signal based upon specified variable values. • Functions to set/query condition variable attributes are also included. Computer Architecture II
Creating Posix Threads int pthread_create(pthread_t *, const pthread_attr_t *, void * (*)(void *), void *); Example call: errcode = pthread_create(&thread_id; &thread_attribute &thread_func; &func_arg); • thread_id is the thread id or handle (used to halt, etc.) • thread_attribute various attributes • standard default values obtained by passing a NULL pointer • thread_func the function to be run (takes and returns void*) • func_arg an argument can be passed to thread_fun when it starts • errorcode will be set nonzero if the create operation fails Computer Architecture II
Terminating Thread Execution • Termination • The thread returns from its starting routine (the main routine for the initial thread). • The thread makes a call to the pthread_exit subroutine (covered below). • The thread is canceled by another thread via the pthread_cancel routine. • The entire process is terminated due to a call to either the exec or exit subroutines. • void pthread_exit (void * retval) • If main() finishes before the threads it has created, and exits with pthread_exit(), the other threads will continue to execute. Otherwise, they will be automatically terminated when main() finishes. • The programmer may optionally specify a termination status, which is stored as a void pointer for any thread that may join the calling thread. • Cleanup: the pthread_exit() routine does not close files; any files opened inside the thread will remain open after the thread is terminated. Computer Architecture II
Creation/termination example #include <pthread.h> #include <stdio.h> #define NUM_THREADS 5 void *PrintHello(void *threadid){ printf("\n%d: Hello World!\n", threadid); pthread_exit(NULL);} int main (int argc, char *argv[]){ pthread_t threads[NUM_THREADS]; int rc, t; for(t=0;t < NUM_THREADS;t++){ printf("Creating thread %d\n", t); rc = pthread_create(&threads[t], NULL, PrintHello, (void *)t); if (rc){ printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_exit(NULL); } Computer Architecture II
Joining Threads • One form of synchronization between threads. (Others: mutexes and condition variables) • Threads • Joinable (another thread may wait for its termination) • Detached • never joinable • Resources released by OS at termination • pthread_join (pthread_t threadid, void **thr_return) • blocks the calling thread until the specified threadid thread terminates. • thr_return gets the value returned ba pthread_exit(). Computer Architecture II
Creating/Joining threads M Master creates threads T0 T1 T2 Join threads Computer Architecture II
Join example #define NUM_THREADS 3 void *BusyWork(void *null) {…} int main (int argc, char *argv[]) { pthread_t thread[NUM_THREADS]; pthread_attr_t attr; int rc, t, status; /* Initialize and set thread detached attribute */ pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); for(t=0;t < NUM_THREADS;t++) { printf("Creating thread %d\n", t); rc = pthread_create(&thread[t], &attr, BusyWork, NULL); if (rc) { printf("ERROR; return code from pthread_create() is %d\n", rc); exit(-1); } } pthread_attr_destroy(&attr); /* Free attribute and wait for the other threads */ for(t=0;t < NUM_THREADS;t++) { rc = pthread_join(thread[t], (void **)&status); if (rc) { printf("ERROR; return code from pthread_join() is %d\n", rc); exit(-1); } printf("Completed join with thread %d status= %d\n",t, status); } pthread_exit(NULL); } Computer Architecture II
Sharing variables: what can go wrong? int counter=0; void *incr(void *arg) { counter++; printf("Thread %u is number %d\n", pthread_self(),counter); } main() { int i; pthread_t tid; for (i=0;i<10;i++) pthread_create(&tid,NULL,incr,NULL); } Computer Architecture II
Mutex • Mutex is an abbreviation for "mutual exclusion“ • thread synchronization • protecting shared data when multiple writes occur • A mutex variable • Only one thread can lock a mutex variable at any given time. • All other threads trying to acquire the lock wait • prevent race conditions (like in the previous example) Computer Architecture II
Mutex variables • declared with type pthread_mutex_t • must be initialized before they can be used • Statically, when it is declared. pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER; • Dynamically, with the pthread_mutex_init() routine. This method permits setting mutex object attributes (we do not discuss them) • The mutex is initially unlocked. Computer Architecture II
Sharing variables: correct example int counter=0; pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; void *incr(void *arg) { pthread_mutex_lock (&mutex); counter++; pthread_mutex_unlock (&mutex); printf("Thread %u is number %d\n", pthread_self(),counter); } main() { int i; pthread_t tid; for (i=0;i<10;i++) pthread_create(&tid,NULL,incr,NULL); } Computer Architecture II
Condition variables • Synchronization mechanism as well • Mutexes: control access to data (no one will access data but the mutex owner) • condition variables allow threads to synchronize based upon the actual value of data (a thread waits until a condition becomes true) • Without condition variables, a thread would have to continually polling, to check if the condition is met (CPU consuming). • A condition variable is always used in conjunction with a mutex lock. Computer Architecture II
Condition variables routines int pthread_cond_wait ( pthread_cond_t *cptr, pthread_mutex_t *mptr); • blocks the calling thread until the specified condition is signalled. • should be called after locking mutex • it automatically releases the mutex while it waits • the mutex shuld be unlock after signal has been received. int pthread_cond_signal( pthread_con_t *cptr); • signals another thread which is waiting on the condition variable • should be called after locking mutex • must unlock mutex in order to let pthread_cond_wait() return int pthread_cond_broadcast( pthread_con_t *cptr); • Used instead of pthread_cond_signal for signaling all waiting threads Computer Architecture II
Condition variable simplest example pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t cond = PTHREAD_COND_INITIALIZER; int value = 0; void * wait_thread (void *arg) { pthread_mutex_lock (&mutex); value = 1; /* Set predicate */ pthread_cond_signal (&cond); pthread_mutex_unlock (&mutex); return NULL; } int main (int argc, char *argv[]){ pthread_t wait_thread_id; pthread_create (&wait_thread_id, NULL, wait_thread, NULL); pthread_mutex_lock (&mutex); while (value == 0) pthread_cond_wait (&cond,&mutex); pthread_mutex_unlock (&mutex); } Computer Architecture II
Thread Safe • It’s not safe to use with threads functions using • static variables • global memory • When using a library with threads first question: is it thread-safe? Computer Architecture II