wait
может вернуться без вызова notify
. Это называется ложным пробуждением . Чтобы справиться с этим, код, использующий условие, всегда должен иметь цикл вокруг wait
, который проверяет, что ожидаемое условие действительно действует. Например:
queue data_queue;
boost::mutex access;
boost::condition cond;
// consumer
data read()
{
boost::mutex::scoped_lock lock(access);
while (queue.is_empty()) {
// this blocks until the data is ready
cond.wait(lock);
}
// queue is ready
return data_from_queue();
}
// producer
void push(data)
{
boost::mutex::scoped_lock lock(access);
// add data to queue
queue.push_back(data);
cond.notify_one();
}
Концептуально «состояние» является своего рода заблуждением. Вместо этого вы можете думать об этом как о сигнале. Вы даете сигнал другому потоку или потокам проснуться, но ничего не обещаете. Просто, «Эй, может быть, есть некоторые данные готовы, почему бы тебе не проверить, а?»