Condition Variables solve this problem.
There are six operations which you can do on a condition variable:
Initialisation.
int pthread_cond_init (pthread_cond_t *cond, pthread_condattr_t *attr);Again to use the default attributes, just pass
NULL as the
second parameter.
Waiting.
int pthread_cond_wait (pthread_cond_t *cond, pthread_mutex_t *mut);This function always blocks. In pseudo-code:
pthread_cond_wait (cond, mut) begin pthread_mutex_unlock (mut); block_on_cond (cond); pthread_mutex_lock (mut); endNote that it releases the mutex before it blocks, and then re-acquires it before it returns. This is very important. Also note that re-acquiring the mutex can block for a little longer, so the the condition which was signalled will need to be rechecked after the function returns.
Signalling.
int pthread_cond_signal (pthread_cond_t *cond);This wakes up at least one thread blocked on the condition variable. Remember that they must each re-acquire the mutex before they can return, so they will exit the block one at a time.
Broadcast Signalling.
int pthread_cond_broadcast (pthread_cond_t *cond);This wakes up all of the threads blocked on the condition variable. Note again they will exit the block one at a time.
Waiting with timeout.
int pthread_cond_timedwait (pthread_cond_t *cond, pthread_mutex_t *mut, const struct timespec *abstime);Identical to pthread_cond_wait(), except it has a timeout. This timeout is an absolute time of day.
struct timespec to {
time_t tv_sec;
long tv_nsec;
};
If a abstime has passed, then pthread_cond_timedwait() returns ETIMEDOUT.
Deallocation.
int pthread_cond_destroy (pthread_cond_t *cond);Bye Bye condition variable :).