8 pthread_mutex_t mutex; /* Protects access to value */
9 pthread_cond_t cond; /* Signals change to value */
10 int value; /* Access protected by mutex */
11 } my_struct_t;
12
13 int main (int argc, char *argv[])
14 {
15 my_struct_t *data;
16 int status;
17
18 data = malloc (sizeof (my_struct_t));
19 if (data == NULL)
20 errno_abort ("Allocate structure");
21 status = pthread_mutex_init (&data->mutex, NULL);
22 if (status != 0)
23 err_abort (status, "Init mutex");
24 status = pthread_cond_init (&data->cond, NULL);
25 if (status != 0)
26 err_abort (status, "Init condition");
27 status = pthread_cond_destroy (&data->cond);
28 if (status != 0)
29 err_abort (status, "Destroy condition");
30 status = pthread_mutex_destroy (&data->mutex);
31 if (status != 0)
32 err_abort (status, "Destroy mutex");
33 (void)free (data);
34 return status;
35 }
When you dynamically initialize a condition variable, you should destroy the condition variable when you no longer need it, by calling pthread_cond_destroy. You do not need to destroy a condition variable that was statically initialized using the PTHREAD_COND_INITIALIZER macro.
It is safe to destroy a condition variable when you know that no threads can be blocked on the condition variable, and no additional threads will try to wait on, signal, or broadcast the condition variable. The best way to determine this is usually within a thread that has just successfully broadcast to unblock all waiters, when program logic ensures that no threads will try to use the condition variable later.
When a thread removes a structure containing a condition variable from a list, for example, and then broadcasts to awaken any waiters, it is safe (and also a very good idea) to destroy the condition variable before freeing the storage that the condition variable occupies. The awakened threads should check their wait predicate when they resume, so you must make sure that you don't free resources required for the predicate before they've done so—this may require additional synchronization.
3.3.2 Waiting on a condition variable
int pthread_cond_wait (pthread_cond_t *cond,
pthread_mutex_t *mutex);
int pthread_cond_timedwait (pthread_cond_t *cond,
pthread_mutex_t *mutex,
struct timespec *expiration);
Each condition variable must be associated with a specific mutex, and with a predicate condition. When a thread waits on a condition variable it must always have the associated mutex locked. Remember that the condition variable wait operation will
All threads that wait on any one condition variable concurrently (at the same time) must specify the
It is important that you test the predicate after locking the appropriate mutex and before waiting on the condition variable. If a thread signals or broadcasts a condition variable while no threads are waiting, nothing happens. If some other thread calls pthread_cond_wait right after that, it will keep waiting regardless of the fact that the condition variable was just signaled, which means that if a thread waits when it doesn't have to, it may never wake up. Because the mutex remains locked until the thread is blocked on the condition variable, the predicate cannot become set between the predicate test and the wait—the mutex is locked and no other thread can change the shared data, including the predicate.
Always test your predicate; and then test it again!