/******************************************************** * An example source module to accompany... * * "Using POSIX Threads: Programming with Pthreads" * by Brad nichols, Dick Buttlar, Jackie Farrell * O'Reilly & Associates, Inc. * ******************************************************** * * cvsimple.c * * Demonstrates pthread condvars. * */ #include <unistd.h> #include <stdio.h> #include <pthread.h> #define NUM_THREADS 3 #define TCOUNT 10 #define COUNT_THRES 12 int condvar_was_hit = 0; int count = 0; int thread_ids[3] = {0,1,2}; pthread_mutex_t count_lock=PTHREAD_MUTEX_INITIALIZER; pthread_cond_t count_hit_threshold=PTHREAD_COND_INITIALIZER; void *inc_count(void *null) { int i=0; for (i=0; i<TCOUNT; i++) { pthread_mutex_lock(&count_lock); count++; printf("inc_counter(): count = %d, unlocking mutex\n", count); if (count == COUNT_THRES) { printf("hit threshold!\n"); pthread_cond_signal(&count_hit_threshold); } pthread_mutex_unlock(&count_lock); } return(NULL); } void *watch_count(void *null) { pthread_mutex_lock(&count_lock); while (count < COUNT_THRES) { pthread_cond_wait(&count_hit_threshold, &count_lock); condvar_was_hit = 1; } pthread_mutex_unlock(&count_lock); return(NULL); } extern int main(void) { int i; pthread_t threads[3]; pthread_create(&threads[0], NULL, watch_count, NULL); sleep(1); pthread_create(&threads[1], NULL, inc_count, NULL); pthread_create(&threads[2], NULL, inc_count, NULL); for (i = 0; i < NUM_THREADS; i++) { pthread_join(threads[i], NULL); } // Nb: it's not certain that we'll hit here. It's possible that the two // inc_count threads could fully run before watch_count begins, and so // pthread_cond_wait() is never called. Or, we could get a spurious // wake-up in watch_count(). Nonetheless, it's very likely that things // will work out as expected, since we're starting watch_count() first. // (Also since the sleep() call was added after watch_count()!) if (condvar_was_hit == 1) printf("condvar was hit!\n"); else if (condvar_was_hit > 1) printf("condvar was multi-hit...\n"); else printf("condvar was missed...\n"); return 0; }