提升条件变量 - 调用"notify_one"堆栈?

Aln*_*tak 3 c++ boost boost-thread

在使用Boost线程的单个生产者/单个消费者应用程序中,如果生产者线程cond_var.notify_one()在消费者线程调用之前进行多次调用,会发生cond_var.wait(lock)什么?

是否会notify_one堆叠额外的呼叫,以便每次呼叫.wait()将与呼叫1:1对应.notify_one()

编辑实现并发队列的一个常见引用示例有以下方法:

void push(Data const& data)
{
    boost::mutex::scoped_lock lock(the_mutex);
    the_queue.push(data);
    lock.unlock();
    the_condition_variable.notify_one();
}

void wait_and_pop(Data& popped_value)
{
    boost::mutex::scoped_lock lock(the_mutex);
    while(the_queue.empty())
    {
        the_condition_variable.wait(lock);
    }

    popped_value=the_queue.front();
    the_queue.pop();
}
Run Code Online (Sandbox Code Playgroud)

我使用了一些非常相似的代码,并且经历了一些奇怪的内存增长,这似乎可以解释为消费者线程没有为每个人唤醒.notify_one()(因为它仍在忙于其他工作),并且想知道是否缺少"堆叠"可能是原因.

如果(有时)消费者线程无法跟上生产者线程,似乎没有堆叠这个代码就会失败.如果我的理论是正确的,我会很感激有关如何修复此代码的建议.

Mik*_*our 7

规范notify_one是:

C++ 11 30.5.1/7:效果:如果任何线程被阻塞等待*this,则取消阻止其中一个theads.

所以答案是否定的:调用notify_one并且notify_all只会唤醒当前正在等待的线程,并且以后不会被记住.

更新:对不起,我误解了这个问题std::condition_variable.毫不奇怪,Boost规范或多或少相同:

如果任何线程当前被阻塞等待*this调用,wait或者timed_wait取消阻塞其中一个线程.

关于你的编辑:如果在有人调用时没有线程等待push,那么下一个要调用的线程pop将不会等待,因为它the_queue不会为空.因此,条件变量不需要记住它不应该等待; 该信息存储在被管理的状态,而不是条件变量.如果消费者无法跟上生产者的步伐,那么您需要加快消费或减缓生产; 你无法对信号机制做任何帮助.