Si vous ne verrouillez pas le mutex dans le codepath qui change la condition et les signaux, vous pouvez perdre des réveils. Considérez cette paire de processus :
Processus A :
pthread_mutex_lock(&mutex);
while (condition == FALSE)
pthread_cond_wait(&cond, &mutex);
pthread_mutex_unlock(&mutex);
Processus B (incorrect) :
condition = TRUE;
pthread_cond_signal(&cond);
Considérons ensuite cet entrelacement possible d'instructions, où condition
commence par FALSE
:
Process A Process B
pthread_mutex_lock(&mutex);
while (condition == FALSE)
condition = TRUE;
pthread_cond_signal(&cond);
pthread_cond_wait(&cond, &mutex);
Le site condition
est maintenant TRUE
mais le processus A est bloqué en attendant la variable de condition - il a manqué le signal de réveil. Si nous modifions le processus B pour verrouiller le mutex :
Processus B (correct) :
pthread_mutex_lock(&mutex);
condition = TRUE;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
...alors ce qui précède ne peut pas se produire ; le réveil ne sera jamais manqué.
(Notez que vous peut déplacer réellement le pthread_cond_signal()
lui-même après le pthread_mutex_unlock()
mais cela peut entraîner un ordonnancement moins optimal des threads, et vous avez déjà nécessairement verrouillé le mutex dans ce chemin de code en raison de la modification de la condition elle-même).