c++ - boost 条件变量 - 是否调用 "notify_one"堆栈?

标签 c++ boost boost-thread

在使用 Boost 线程的单一生产者/单一消费者应用程序中,如果生产者线程在消费者线程调用 cond_var 之前多次调用 cond_var.notify_one() 会发生什么情况。等待(锁定) ?

是否会堆叠对 notify_one 的额外调用,这样每次对 .wait() 的调用都会与 .notify_one()< 1:1 对应调用?

编辑 A commonly quoted example实现并发队列有这些方法:

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();
}

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

如果(有时)消费者线程跟不上生产者线程,那么如果没有堆栈,这段代码似乎会失败。如果我的理论是正确的,我将不胜感激有关如何修复此代码的建议。

最佳答案

notify_one 的规范是:

C++11 30.5.1/7: Effects: If any threads are blocked waiting for *this, unblocks one of those theads.

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

更新:抱歉,我将问题误读为 std::condition_variable。毫不奇怪,Boost规范或多或少相同:

If any threads are currently blocked waiting on *this in a call to wait or timed_wait, unblocks one of those threads.

关于您的编辑:如果有人调用 push 时没有线程等待,那么下一个调用 pop 的线程将根本不会等待,因为 the_queue 不会为空。所以条件变量不需要记住它不应该等待;该信息存储在被管理的状态中,而不是条件变量中。如果消费者跟不上生产者,那么你要么加快消费速度,要么减慢生产速度;您无法对信号机制做任何事情来帮助解决这个问题。

关于c++ - boost 条件变量 - 是否调用 "notify_one"堆栈?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14582505/

相关文章:

c++ - 为什么只能在头文件中实现模板?

c++ - 如何使用 gnu_parallel 运行多个可执行文件和/或 bash 脚本?

c++ - 虚拟析构函数如何工作?

c++ - 枚举唯一的无向路径的有效方法

c++ - Boost::threads 在调试中工作,在发布时不工作

c++ - boost::thread 应用程序,奇怪的数据竞争报告

c++ - 动态加载库中的静态 C++ 对象是否在 dlopen() 返回之前初始化?

c++ - 在 Spirit.X3 中处理带引号和不带引号的字符串的最简洁方法

c++ - 从 vector<string> 中查找字符串的第一次出现

c++ - 超过 32705 个线程时 boost::thread_resource_error