伪唤醒的场景
1个producer,生产好了notify others。
假设有多个consumer,队列的consumer必须调用wait,我们知道wait调用时,实际是经过的unlock->wait
,即会释放当前cond的锁。
而consumer的wait被some notify唤醒时,实际经过了wait->getlock
的过程,很不巧的是,如果这个过程不是原子操作,刚刚wait,资源被another consumer率先getlock
,然后消费并unlock
,等orig comsumergetlock
时,仅有的资源其实已经没有了,再去取资源会得到错误。
正确的做法是在wait返回后,继续再次的检查资源,直到resource != null
。
posix pthread wait处理
pthread_mutex_lock(&mut);
while(resource != null);
pthread_cond_wait(&cond,&mut);
pthread_mutex_unlock(&mut); //推荐马上unlock.可能consumer耗时很长,不要挂锁太长时间。
//consumer eating....
...
c++ thread
thread的condition_variable的wait成员函数已经实现了上面的点。
std::mutex mut;
std::queue<data_chunk> data_queue; // 1
std::condition_variable data_cond;
void consumer{
std::unique_lock<std::mutex> lk(mut);
data_cond.wait(lk,[]{return !data_queue.empty();});
...
}
多个consumer嗷嗷待哺. 队列模型来讲,由于是notify_one
的方式,先喂哪个,producer妈妈也不知道。