这是大多数示例中使用条件变量的方式:
std::mutex mutex_; //declared somehere
主题1:
if (!pred) {
std::unique_lock<std::mutex> lock(mutex_);
cv_.wait(lock, [this](){return pred});
}
主题2:
//makes pred true
cv_.notify_one();
似乎有一个窗口,线程1检查pred,发现它是假的并继续获取锁。但是,在它可以之前,线程2使得pred为真,并通知条件变量并继续前进。线程1现在获取锁定并且卡在此条件变量上。
这种情况通常如何处理?因为有人提到在通知之前采取锁定是一种悲观,因此不应该这样做。
我知道我可以使用超时但这仍然不是解决这个问题的方法。这是否意味着在条件变量上等待/通知,如果不存在竞争条件,总是需要锁定?
修改
有一条评论提到在thread2中,我们应该在使谓词“真实”之前获得相同的锁定。但是,请考虑以下情形:
有一个生成器(thread1)和一个使用者(thread2)的有界队列。假设队列的大小为1000.我们将当前队列大小的计数保持为原子int,以便生产者和消费者可以在不进行锁定的情况下同时修改它。 在上面的例子中,谓词是:队列的大小&lt; 1000.
现在,如果在thread2中,我在修改这个谓词之前进行锁定,即递减计数,它是否会破坏计数为原子的整个目的?此外,我希望它是原子的,因为通常的操作(即当队列大小<1000时)会很快。