开发者

pthread_cond_broadcast does not work?

开发者 https://www.devze.com 2023-04-01 07:15 出处:网络
I have write this program: pthread_cond_t placeFootCondition; pthread_mutex_t rf,lf; void* rss(void* in){

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(&placeFootCondi开发者_高级运维tion,&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???


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.


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号