Presentation is loading. Please wait.

Presentation is loading. Please wait.

Pthreads – Create and Join

Similar presentations


Presentation on theme: "Pthreads – Create and Join"— Presentation transcript:

1 Pthreads – Create and Join
IEEE Portable Operating System Interface Standard (POSIX) Spawn an attached thread pthread_create (&thread1, NULL, proc1, &arg) . pthread_join(thread1, status) Thread execution void proc1(&arg) { // Thread code return(*status); } Detatched threads Join is not needed The OS destroys thread resources when they terminate A parameter in the create call indicates a detached thread Note: The Pthreads library must be available : #include <pthread.h>

2 Executing a Thread

3 Locks Declare a lock: pthread_mutex_t mutex;
Declare a mutex attribute: pthread_mutexattr_t mta; Initializing an attribute (spin_only, limited_spin, no_spin, recursive, metered) pthread_mutexattr_init(&mta); pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_RECURSIVE); pthread_mutexattr_setname_np(&mta, "My Mutex"); Initialize a mutex pthread_mutex_init(&mutex, NULL); // Use defaults pthread_mutex_init(&mutex, &mta); // or use designated attributes Enter and release Pthread_mutex_lock(&mutex); and pthread_mutex_unlock(&mutex); Try Lock without block: pthread_mutex_trylock(&mutex); Release resources pthread_mutex_destroy(mutex); and pthread_mutexattr_destroy(&mta);

4 Semaphores Initialize
Required: # include <semaphore . h> Semaphores are not part of Pthreads Initialize int sem_init ( sem_t *sem, int shared, /* non-zero to share between processes */ unsigned initial_val ) ; /* one works like a mutex */ Destroy semaphore: int sem_destroy ( sem_t sem) ; Post (V): int sem_post ( sem_t sem ) ; Wait (P): int sem_wait ( sem_t sem ) ; Semaphores can count up or down and can start with any positive integer value

5 Condition Variables counter() { . . pthread_mutex_lock(&mutex); c--; if (c == 0) pthread_cond_signal(cond); . . pthread_mutex_unlock(&mutex); } action() { . . pthread_mutex_lock(&mutex); while (c <> 0) pthread_cond_wait(cond,mutex); pthread_mutex_unlock(&mutex); take_action(); } Note: Signals are missed if a thread is not waiting when they are sent

6 Read-Write Locks Initialize Locking
More than reader is allowed, however, writing is exclusive Initialize int pthread_rwlock_init (pthread_rwlock_t *readWriteLock , const pthread_rwlockattr_t attr_p ) ; Locking i n t pthread_rwlock_rdlock( pthread_rwlock_t readWriteLock ) ; i n t pthread_rwlock_wrlock( pthread_rwlock_t readWriteLock ) ; Unlock: int pthread_rwlock_unlock( pthread_rwlock_t readWriteLock ) ; Destroy: int pthread_rwlock_destroy ( pthread_rwlock_t readWriteLock ) ; Practical Example: Multithreaded linked lists or binary trees

7 Hello World: Pthreads Make sure to include: <stdio.h>, <stdlib.h>, and <pthread.h> void* Hello ( void* myRank ) { printf ( "Hello from thread %ld\n" , (long)(*myRank) ) ; return NULL ; } void main ( int argc , char argv [ ] ) { long t; pthread_t[] threadHandles ; int threads = strtol ( argv [ 1 ] , NULL , 1 0 ) ; thread_handles = malloc ( threads * sizeof( pthread_t ) ) ; for ( t = 0 ; t< threads; t ++ ) pthread_create(&threadHandles [ t ] , NULL ,Hello , ( void *) &t ); printf ( "Hello from the main thread\n" ) ; for ( t= 0 ; t < threads; t ++) pthread_join ( threadHandles [ t ] , NULL ) ; free( threadHandles ) ;

8 Matrix Multiplication
Pthreads Version Matrix Multiplication void* matrixMult( void *rank ) { i nt r, c , myM = m / (int)threads ; long myRank = (long)(*rank); int startRow = myRank * myM ; int lastRow = (rank+1) * myM − 1 ; for ( r = startRow ; r <= lastRow ; r++) { y[r] = ; for ( c = 0 ; c < n ; c++) y[ r ] += A[r][c] x[c] ; } return NULL ; Sequential Version for ( r = 0 ; r < m ; r++) { y [ r ] = 0.0 ; for ( c = 0 ; c < n ; c++) y[ r ] += A[ r][ c] * x[ c ] ; } Assumption: Even number of rows per processor and m, n, threads are global variables Note: Works because we don't alter the original data

9 Failed Pthread version
Calculate π Calculation of π Failed Pthread version π = 4(1-1/3+1/5-1/7+ … ) Sequential version double factor = 1.0, sum = 0.0; for (i=0; i<n; i++, factor = -factor) { sum += factor/2*i+1; } pi = 4*sum; void* Thread_sum ( void *rank ) { long myRank = ( long ) (*rank) ; double factor ; long long i, myN = n/threads; long long first = myN*myRank long long last = first+myN; if ( first % 2 == 0) factor = ; else factor = −1.0; for ( i=first; i<last ; i++, factor =−factor ) { sum += factor / ( 2*i + 1 ) ; } } The statement that updates sum is a critical section

10 Busy Wait Solutions Update sum in the loop Sum after the loop
void* Thread_sum ( void *rank ) { long myRank = ( long ) (*rank) ; double factor, sum=0; long long i, myN = n/threads; long long first = myN*myRank; long long last = first + myN; if ( first % 2 == 0) factor = ; else factor = −1.0; for (i=first; i<last ; i++,factor=-factor) { while (flag !=myRank); sum += factor / ( 2*i + 1 ) ; flag = (flag+1)%threads; } } void* Thread_sum ( void *rank ) { long myRank = ( long ) (*rank) ; double factor, mySum=0.0; long long i, myN = n/threads; long long first = myN*myRank; if ( first % 2 == 0) factor = 1.0; e l s e factor = −1.0; for (i=first;i<first+myN;i++,factor=−factor) { mySum += factor / ( 2*i + 1 ) ; } while (flag !=myRank); sum += mySum; flag = (flag+1)%threads; }

11 MUTEX Solution Time Comparison
void* Thread_sum ( void *rank ) { long myRank = ( long ) (*rank) ; double factor, mySum=0; long long i, myN = n/threads; long long first = myN*myRank, first+myN; if ( first % 2 == 0) factor = ; e l s e factor = −1.0; f o r (i=first; i<last ; i++, factor =−factor) { mySum += factor / ( 2*i + 1 ) ; } pthread_mutex_lock(&mutex) sum += mySum; pthread_mutex_unlock(&mutex); } Time Comparison Busy wait slower, but order of execution is deterministic

12 Sending Messages to Threads
Each Processor stores a message to the next array index Solution with Mutexes is not obvious Initialize the Semaphores to 0 (locked), then unlock before lock Failure: Critical Section Solution with Semaphores void* Send_msg ( void* arg ) { long rank = ( long )(*arg) ; long to = (rank+1)%threads ; char *msg=malloc (MAX*sizeof (char)) ; sprintf (msg ,"%ld --> %ld, rank, to) ; msgs[ to ] = msg ; printf ("%ld>%s\n",rank,msgs[rank]) ; } void* Send_msg ( void* arg ) { long rank = ( long ) (*arg) ; long to = (rank+1)%threads ; char *msg = malloc(MAX*sizeof(char)); sprintf (msg, %ld --> %ld", rank, to) ; msgs[ to ] = msg ; sem_post(&semaphores [ to] ) ; sem_wait(&semaphores [ rank ] ) ; printf (%ld > %s\n", rank , msgs[rank ] ) ; }

13 Barriers: Condition variables
Note: Pthreads does provide for barriers /* Shared */ int counter = 0 ; pthread_mutex_t mtx ; pthread_cond_t cnd ; /* Thread work */ /* Start of the barrier */ pthread_mutex_lock(&mtx ) ; counter ++; i f ( counter == threads) { counter = 0 ; pthread_cond_broadcast(&cnd ) ; } else { while (pthread_cond_wait(&cnd,&mtx)!=0); } pthread_mutex_unlock(&mtx ) ; /* More thread work */ Barriers: Mutex int thread_count ; pthread_mutex_t mtx; /* Thread work */ /* Start of the barrier */ pthread_mutex_lock(&mtx ) ; counter ++; pthread_mutex_unlock(&mtx) ; while ( counter < thread_count ) ; } // Inefficient (busy-wait ) /* More thread work */

14 Read-Write Locks and Lists
Accessing the list pthread_rwlock_rdlock(&rwlock ) ; entry = Find( key ) ; pthread_rwlock_unlock(&rwlock ) ; Inserting into the list pthread_rwlock_wrlock(&rwlock ) ; Insert ( entry ) ; Removing from the list Delete ( entry ) ;


Download ppt "Pthreads – Create and Join"

Similar presentations


Ads by Google