/* * Synchronization via condition variables. * * This program contains a bug. Find it and fix it. */ #include #include #include #include #include #include int coin_flip; // 0 or 1, heads or tails bool coin_flip_done; // states whether 'coin_flip' contains valid result // protects coin_flip_done; pthread_mutex_t coin_flip_done_lock = PTHREAD_MUTEX_INITIALIZER; pthread_cond_t coin_flip_done_cond = PTHREAD_COND_INITIALIZER; static void * producer(void *_items_to_produce) { int i, n = *(int *)_items_to_produce; for (i = 0; i < n; i++) { pthread_mutex_lock(&coin_flip_done_lock); while (coin_flip_done) pthread_cond_wait(&coin_flip_done_cond, &coin_flip_done_lock); coin_flip = rand() % 2; coin_flip_done = true; printf("thread %p: flipping coin %d\n", (void *)pthread_self(), coin_flip); pthread_cond_signal(&coin_flip_done_cond); pthread_mutex_unlock(&coin_flip_done_lock); } return NULL; } static void * consumer(void *_items_to_consume) { int i, n = *(int *)_items_to_consume; for (i = 0; i < n; i++) { pthread_mutex_lock(&coin_flip_done_lock); while (!coin_flip_done) pthread_cond_wait(&coin_flip_done_cond, &coin_flip_done_lock); coin_flip_done = false; printf("thread %p: coin flip outcome was %d\n", (void *)pthread_self(), coin_flip); pthread_cond_signal(&coin_flip_done_cond); pthread_mutex_unlock(&coin_flip_done_lock); } return NULL; } int main() { int i, N = 4; pthread_t t[N]; int items [N] = { 3, 2, 4, 1 }; void * (*func [N])(void*) = { consumer, consumer, producer, producer }; srand(getpid()); for (i = 0; i < N; i++) pthread_create(&t[i], NULL, func[i], items + i); for (i = 0; i < N; i++) pthread_join(t[i], NULL); return 0; }