简体   繁体   中英

Second thread doesn't wake up from cond_wait

We are trying to find a good synchronization for Game of life.

Therefore we have one printer thread and currently two threads that calculate the new generation of cells to be printed out next.

The calculating threads can only start calculating the new generation of the game if the old one has already been printed.

Therefore we use pthread_cond_signal() from the printer thread that is supposed to wake up both calculating threads.

For some reason only one thread wakes up at pthread_cond_wait()

We already tried to use broadcast instead of signal, but that didn't have any effect.

This is what our printer thread does:

field -> printed = true;
//pthread_mutex_unlock(&(field -> print_mutex));
int status = pthread_cond_signal(&(field -> print_signal));

This is what our calculating threads do:

while(!field -> printed){
    printf("waiting for print_signal: %d\n", field -> printed);
    pthread_mutex_unlock(&(field -> print_mutex));
    pthread_cond_wait(&(field -> print_signal), &(field -> print_mutex));
    printf("print_signal received: %d\n", field -> printed);
}
printf("print_signal received2: %d\n", field -> printed);
pthread_mutex_unlock(&(field -> print_mutex));

Afterwards the calculating threads do their calculation and wait till every thread completed before they set the field -> printed back to false.

We feel like we still don't really understand how to use the mutex correctly.

pthread_cond_signal() signals exactly one of all threads waiting.

From Linux's pthread_cond_signal documentation:

pthread_cond_signal restarts one of the threads that are waiting on the condition variable cond.

To inform all threads waiting use pthread_cond_broadcast .

From Linux's pthread_cond_broadcast documentation:

pthread_cond_broadcast restarts all the threads that are waiting on the condition variable cond.

The POSIX documentations says:

The pthread_cond_broadcast() function shall unblock all threads currently blocked on the specified condition variable cond.

The pthread_cond_signal() function shall unblock at least one of the threads that are blocked on the specified condition variable cond (if any threads are blocked on cond).


Also you want to lock the mutex before calling pthread_cond_wait() . The moment the thread enters the waiting-state the mutex gets unlocked implicitly.

Also note, that after pthread_cond_wait() returned the mutex is locked again.

To follow this concpet you could change your code to look like this:

pthread_mutex_lock(&(field -> print_mutex));

while (!field -> printed)
{
  pthread_cond_wait(&(field -> print_signal), &(field -> print_mutex));
}

pthread_mutex_unlock(&(field -> print_mutex));

Also make sure to not write to the flag without protection

pthread_mutex_lock(&(field -> print_mutex));

field -> printed = true;
pthread_cond_signal(&(field -> print_signal));

pthread_mutex_unlock(&(field -> print_mutex));

And finally take this advice: In your real code add error checking to *all those pthread_*() calls!


And^2 you did make sure condition and mutex got initalised properly, didn't you? ;-)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM