8. Variables de condition
Une variable de condition sert à attendre qu’un prédicat sur un état partagé devienne vrai. Elle n’est ni le prédicat, ni un verrou, ni une mémoire persistante des signaux.
Le patron sûr est :
Code (c) · sélectionner pour copier
pthread_mutex_lock(&m);
while (!predicat_partage) {
pthread_cond_wait(&condition, &m);
}
/* le mutex est de nouveau détenu */
utiliser_ou_modifier_etat();
pthread_mutex_unlock(&m);
pthread_cond_wait doit recevoir un mutex déjà détenu. L’opération libère atomiquement le mutex et bloque, puis réacquiert le mutex avant de retourner. Cette atomicité ferme la fenêtre du réveil perdu.
La vérification emploie while, et non if, parce que :
- des réveils parasites sont permis;
- un autre thread peut consommer la condition avant que le thread réveillé ne reprenne le mutex;
- le signal annonce qu’il faut retester, non que le prédicat est garanti.
pthread_cond_signal réveille au moins un attenteur sans garantir lequel. Si personne n’attend, le signal n’est pas mémorisé. pthread_cond_broadcast réveille tous les attenteurs, qui doivent ensuite réacquérir le mutex et retester.
Le thread producteur modifie normalement le prédicat sous le même mutex, puis signale. pthread_cond_init ou PTHREAD_COND_INITIALIZER crée l’objet; pthread_cond_destroy n’est valide que lorsqu’aucun thread n’attend.