Conditional
variables are like flags.
When
you want to wake up some threads when some condition is met, conditional
variables are used. It is used with mutex always, since the conditional variable
itself is protected by the mutex.
- int pthread_cond_init( pthread_cond_t * cond, pthread_condattr_t * cond_attr );
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
- int pthread_cond_destroy ( pthread_cond_t * cond );
- int pthread_cond_wait( pthread_cond_t * cond, pthread_mutex_t * mutex);
- int pthread_cond_timedwait( pthread_cond_t * cond, pthread_mutex_t *mutex, const struct timespec * abstime );
- int pthread_cond_signal( pthread_cond_t * cond );
- int pthread_cond_broadcast( pthread_cond_t * cond );
One Object or Class which needs to be protected by single lock. But, both producer and consumer threads will try to access the object. If both do not have any condition for their execution, then there are no issues. If they are depend on each other, like the consumer needs to object to have the count not to be zero, the consumer has some condition on its execution. Similarly, the producer will have the condition the queue needs to have some slots. In such a case, if any one of them holds the lock and waits for others to satisfy the condition, then the others cannot do simply because the lock is hold by the waiting one. So, release the key just before waiting.
Assume accessing a toilet, but there is no toilet paper. Then, leave the key and wait on the bench. Let the attender use the key to fill the paper. If use spinlock, you cannot wait, take the key, check the paper, leave the key continuously till it is getting filled. Attender also will take the key, fill the paper, leave the key till it is getting emptied. If there is paper, then no issues, just keep on hold the key, finish your job and leave the key, come out.
Same mutex can be used on multiple condition variables, but not the vice-versa. For a single variable "size of queue" protected by a single mutex, there can be two conditions that "wait for empty space in the queue" and "wait for any element in the queue". So, two different conditional variables associated with same mutex. But, there is no sense that two mutexes are used for one condition variable.
If more than one predicate condtions are associated with single condition variable, then "broadcast" will wake-up all threads. The threads for which the condition became true will continue executions. The wrong ones will go to sleep again. However, it represents a weaker condition than the conditions being checked by individual threads.
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int main( int argc, char ** argv ) {
:
pthread_cond_broadcast( &cond );
return 0;
}
void * temp_func( void * arg ) {
pthread_mutex_lock( &mutex );
while (!p) { // While the condition/predicate/assertion that we are waiting for is not true...
pthread_cond_wait( &cond, &mutex ); // Wait on this monitor's lock and condition variable.
}
// Do critical processing
pthread_mutex_unlock( &mutex ) ;
return 0;
}
No comments:
Post a Comment