Reputation: 135
I have write this program:
pthread_cond_t placeFootCondition;
pthread_mutex_t rf,lf;
void* rss(void* in){
while(1){
pthread_mutex_lock(&rf);
printf ( "rss: waiting for condition\n" );
pthread_cond_wait(&placeFootCondition,&rf);
printf ( " Right Single Support \n" );
sleep(1);
pthread_mutex_unlock(&rf);
}
}
void* lss(void* in){
while(1){
pthread_mutex_lock(&lf);
printf ( "lss: waiting for condition\n" );
pthread_cond_wait(&placeFootCondition,&lf);
printf ( "Left Single Support \n" );
sleep(1);
pthread_mutex_unlock(&lf);
}
}
int main(){
int rc;
pthread_mutex_init(&rf,NULL);
pthread_mutex_init(&lf,NULL);
pthread_cond_init(&placeFootCondition,NULL);
pthread_create(&t1,NULL,rss,NULL);
pthread_create(&t2,NULL,lss,NULL);
sleep(1);
rc=pthread_cond_broadcast(&placeFootCondition);
if(rc!=0) printf ( "rc=%i\n",rc );
sleep(5);
}
But the output of the program is
rss: waiting for condition
lss: waiting for condition
Right Single Support
rss: waiting for condition
pthread_cond_broadcast(&placeFootCondition) should not wake up all threads???
Upvotes: 2
Views: 2860
Reputation: 182761
In addition to the incorrect use of different mutexes, your program follows no logic. What is the condition the condition variable indicates? (This is called the 'predicate'.) Without a predicate, you will get lost wakeups.
The pthread_cond_wait
function, despite its name, is not a conditional wait. It is an unconditional wait for a condition. You must call it only when the condition is to be waited for.
Suppose you and your sister share a car, and you can't use the car when your sister has borrowed it, so you wait for your sister to come home. Well, if she's already home, you're going to be waiting a long time! (And if she comes home but by the time you get to the car she and the car are gone, you have to wait again.)
The pattern is (for you):
// let's get the car
pthread_mutex_lock(&mutex_that_protects_car);
while(car==SISTER_HAS_CAR) // car is gone
pthread_mutex_wait(&condition_variable, &mutex_that_protects_car);
car=BROTHER_HAS_CAR; // it's my car now
pthread_mutex_unlock(&mutex_that_protects_car);
// we now have the car
and for your sister:
// we are done with the car, make it free
pthread_mutex_lock(&mutex_that_protects_car);
car=CAR_IS_FREE;
pthread_cond_broadcast(&condition_variable); // he can have the car
pthread_mutex_unlock(&mutex_that_protects_car);
Notice that the car's condition must be protected by a single, shared mutex. The state of the car is the predicate, and it is protected by the mutex and shared by the threads.
Notice also that we call pthread_cond_wait
while, and only when, the condition is to be waited for. We do not wait when the car is free. And we keep waiting in case she grabbed the car again before we could grab it.
Upvotes: 1
Reputation: 182639
Here is what you are doing:
pthread_cond_wait(&placeFootCondition,&rf); /* First thread uses rf mutex. */
pthread_cond_wait(&placeFootCondition,&lf); /* Second thread uses lf mutex. */
Here is what the standard says about using different mutexes:
When a thread waits on a condition variable, having specified a particular mutex to either the pthread_cond_timedwait() or the pthread_cond_wait() operation, a dynamic binding is formed between that mutex and condition variable that remains in effect as long as at least one thread is blocked on the condition variable. During this time, the effect of an attempt by any thread to wait on that condition variable using a different mutex is undefined.
Bottom line, from every thread you should use the same mutex when waiting on a condition variable.
Upvotes: 5