Да, вам нужно заблокировать мьютекс где-нибудь на стороне настройки сигнализации / буфера.
Условная переменная должна всегда быть в паре с некоторым условием по общему состоянию, которого ожидает ожидающий поток - поэтому она называется условной переменной . Сторона ожидания должна всегда повторно проверять условие, которого она ожидает после возврата pthread_cond_wait()
- ей разрешено возвращаться рано, даже если об этом еще не было сообщено. Почти во всех случаях это означает, что вы должны вызывать pthread_cond_wait()
в цикле, который проверяет условие:
pthread_mutex_lock(&mut);
while (!buffer_is_set())
pthread_cond_wait(&cond, &mut);
consume_buffer();
pthread_mutex_unlock(&mut);
Условие buffer_is_set()
обязательно рассмотрит некоторое общее состояние, которое обновляет другой поток, поэтому другой поток должен также заблокировать мьютекс, чтобы предотвратить гоночный доступ к этому состоянию:
pthread_lock(&mut);
setting_buffer(); /* Now buffer_is_set() will return true */
pthread_cond_signal(&cond);
pthread_unlock(&mut);
Обратите внимание, что мьютекс нужно блокировать только вокруг вызова setting_buffer()
- безопасно звонить pthread_cond_signal()
после разблокировки мьютекса.