/* threads.c Jeff Ondich, 4/12/04 Updated 4/23/10 A simple demonstration of the use of pthreads. This demo uses two binary semaphores to force strict alternation between a pair of threads. Note that the two thread procedures include delay loops. The point of this is to illustrate the passing of parameters to the thread procedures via the fourth pthread_create parameter. To compile: gcc -Wall -o threads threads.c -lpthread */ #include #include #include #define COUNTER_LIMIT 20 int gSharedCounter = 0; pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER; pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER; void *threadMainA( void *arg ); void *threadMainB( void *arg ); void delay( int limit ); int main() { pthread_t threadA, threadB; /* Parent process locks the B mutex to make sure thread A goes first after the threads are spawned. */ pthread_mutex_lock( &mutexB ); /* Spawn the threads. */ if( pthread_create( &threadA, NULL, threadMainA, (void *)20000 ) != 0 ) { perror( "Can't create thread A" ); exit( 1 ); } if( pthread_create( &threadB, NULL, threadMainB, (void *)10000 ) != 0 ) { perror( "Can't create thread B" ); exit( 1 ); } /* Wait for children to return. If you don't wait for them, the process will return from main(), and thus shut down the whole process, including the threads. */ pthread_join( threadA, NULL ); pthread_join( threadB, NULL ); return 0; } void *threadMainA( void *arg ) { while( 1 ) { pthread_mutex_lock( &mutexA ); if( gSharedCounter >= COUNTER_LIMIT ) { pthread_mutex_unlock( &mutexB ); break; } gSharedCounter++; fprintf( stderr, "Thread A: %d\n", gSharedCounter ); fflush( stderr ); pthread_mutex_unlock( &mutexB ); delay( (int)arg ); } return NULL; } void *threadMainB( void *arg ) { while( 1 ) { pthread_mutex_lock( &mutexB ); if( gSharedCounter >= COUNTER_LIMIT ) { pthread_mutex_unlock( &mutexA ); break; } gSharedCounter++; fprintf( stderr, "Thread B: %d\n", gSharedCounter ); fflush( stderr ); pthread_mutex_unlock( &mutexA ); delay( (int)arg ); } return NULL; } void delay( int limit ) { int j, k; for( j=0; j < limit; j++ ) { for( k=0; k < limit; k++ ) { } } }