/* File: * ex4.7_pth_pc_both.c * * Purpose: * Implement pthread producer-consumer synchronization * using a mutex. In this version each thread * is both a producer and a consumer. * * Input: * none * * Output: * messages received by each thread * * Compile: gcc -g -Wall -o ex4.7_pth_pc_both ex4.7_pth_pc_both.c -lpthread * * Usage: * ex4.7_pth_pc_both * */ #include #include #include #include const int MAX_STRING = 99; int thread_count; int msg = 0; /* Is there a message available */ int receiver; /* Which thread should receive the message */ char* message; /* Contents of the message */ pthread_mutex_t mutex; void Usage(char* progname); /* Thread function */ void* Thread_work(void* rank); /*-----------------------------------------------------------------*/ int main(int argc, char* argv[]) { long thread; pthread_t* thread_handles; message = malloc(MAX_STRING*sizeof(char)); if(argc != 2) Usage(argv[0]); thread_count = strtol(argv[1], NULL, 10); /* allocate array for thread handles */ thread_handles = malloc(thread_count*sizeof(pthread_t)); /* initialize mutex */ pthread_mutex_init(&mutex, NULL); /* start threads */ for(thread = 0; thread < thread_count; thread++) { pthread_create(&thread_handles[thread], NULL, Thread_work, (void*) thread); } /* wait for threads to complete */ for(thread = 0; thread < thread_count; thread++) { pthread_join(thread_handles[thread], NULL); } pthread_mutex_destroy(&mutex); free(thread_handles); return 0; } /*------------------------------------------------------------------- * * Function: Thread_work * Purpose: Each thread creates a message, makes it available * to another thread, and prints the message it * received * In arg: rank * Global var: mutex, msg, message */ void *Thread_work(void* rank) { long my_rank = (long) rank; int send = 0, recv = 0; while(1) { pthread_mutex_lock(&mutex); if(msg) { if (my_rank == receiver && !recv) { printf("Th %ld > Received: %s\n", my_rank, message); msg = 0; recv = 1; } } else { if (!send) { sprintf(message, "hello from rank %ld", my_rank); msg = 1; send = 1; receiver = (my_rank+1) % thread_count; } } pthread_mutex_unlock(&mutex); if (send && recv) break; } return NULL; } /*-------------------------------------------------------------------- * Function: Usage * Purpose: Print command line for function and terminate * In arg: prog_name */ void Usage(char* progname) { fprintf(stderr, "Usage: %s \n", progname); exit(0); }