Condition Variables


Mutexes allow you to avoid data races, unfortunately while they allow you to protect an operation, they don't permit you to wait until another thread completes an arbitrary activity.

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);
end

Note 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.
More about this later.

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 :).

<<< Contents >>>


Andrae Muys