Несмотря на название, pthread_cond_wait
является условным un условным ожиданием для условия. Вы не должны звонить pthread_cond_wait
, если вы не подтвердили, что есть что-то, что нужно ждать, и то, что его ждет, должно быть защищено соответствующим мьютексом.
Переменные состояния не имеют состояния, и приложение должно хранить состояние ожидаемой вещи, называемой «предикатом».
Канонический рисунок:
pthread_mutex_lock(&mutex);
while(!ready_for_me_to_do_something)
pthread_cond_wait(&condvar, &mutex);
do_stuff();
ready_for_me_to_do_something=false; // this may or may not be appropriate
pthread_mutex_unlock(&mutex);
и
pthread_mutex_lock(&mutex);
ready_for_me_to_do_something=true;
pthread_cond_broadcast(&condvar);
pthread_mutex_unlock(&mutex);
Обратите внимание, как этот код поддерживает состояние в переменной ready_for_me_to_do_something
, и ожидающий поток ожидает в цикле, пока эта переменная не станет true. Обратите внимание, как мьютекс защищает эту разделяемую переменную и защищает условную переменную (потому что она также разделяется между потоками).
Это не единственный правильный способ использования условной переменной, но очень легко столкнуться с проблемами при любом другом использовании. Вы звоните pthread_cond_wait
, даже если нет причин ждать. Если вы ждете, пока ваша сестра вернется домой с машиной, прежде чем использовать ее, а она уже вернулась, вы будете ждать долго.