pthread_cond_broadcast не работает? - PullRequest
0 голосов
/ 02 сентября 2011

Я написал эту программу:

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

Но вывод программы

rss: waiting for condition
lss: waiting for condition
              Right Single Support 
rss: waiting for condition

pthread_cond_broadcast (& placeFootCondition) не должен пробуждать все потоки ???

Ответы [ 2 ]

3 голосов
/ 02 сентября 2011

Вот что вы делаете:

pthread_cond_wait(&placeFootCondition,&rf); /* First thread uses rf mutex. */

pthread_cond_wait(&placeFootCondition,&lf); /* Second thread uses lf mutex. */

Вот что стандарт говорит об использовании различных мьютексов:

Когда поток ожидаетусловная переменная, указав конкретный мьютекс для операции pthread_cond_timedwait () или pthread_cond_wait (), между этим мьютексом и условной переменной формируется динамическое связывание, которое действует до тех пор, пока по условной переменной заблокирован хотя бы один поток,В течение этого времени эффект попытки любого потока ожидать этой условной переменной с использованием другого мьютекса не определен .


Bottomстрока, из каждого потока вы должны использовать один и тот же мьютекс при ожидании переменной условия.

0 голосов
/ 02 сентября 2011

В дополнение к некорректному использованию различных мьютексов ваша программа не следует логике.На какое условие указывает переменная условия?(Это называется «предикатом».) Без предиката вы получите потерянные пробуждения.

Функция pthread_cond_wait, несмотря на свое название, не является условным ожиданием.Это безусловное ожидание для условия.Вы должны вызывать его только тогда, когда нужно ждать условия.

Предположим, вы и ваша сестра делите машину, и вы не можете пользоваться машиной, когда ваша сестра одолжила ее, поэтому вы ждете свою сеструприйти домой.Ну, если она уже дома, ты будешь ждать долго!(И если она придет домой, но к тому времени, как вы доберетесь до машины, она и машина уйдут, вам придется снова подождать.)

Шаблон (для вас):

// 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

и для вашей сестры:

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

Обратите внимание, что состояние автомобиля должно быть защищено одним общим мьютексом.Состояние автомобиля является предикатом, и оно защищено мьютексом и совместно используется потоками.

Обратите также внимание, что мы вызываем pthread_cond_wait в то время и только тогда, когда следует ожидать условия.Мы не ждем, когда машина освободится.И мы продолжаем ждать, если она снова схватит машину, прежде чем мы сможем ее схватить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...