【问题标题】:What's the difference between notify_all() and notify_one() of std::condition_variable?std::condition_variable 的 notify_all() 和 notify_one() 有什么区别?
【发布时间】:2012-02-19 09:45:23
【问题描述】:

目前,我正在使用 C++11 中的std::thread 实现一个多线程项目。我使用std::condition_variable 来同步线程。具体来说,一个消费者函数调用std::condition_variable的成员函数wait()来等待来自全局任务队列的任务,另一个生产者函数生成任务并将其放入队列。但是我不知道notify_all()std::condition_variable 的成员函数notify_one() 之间的区别。我应该在生产者函数中使用哪个函数?谢谢!

【问题讨论】:

    标签: c++ multithreading c++11 condition-variable


    【解决方案1】:

    如果条件变量上阻塞了十个线程,例如,notify_one() 将仅解除阻塞一个线程,而notify_all() 将全部解除阻塞。在您的情况下,您需要使用notify_one(),这样您就不会唤醒没有任何工作等待它们的线程。

    【讨论】:

    • 谢谢,GMan。我从网上阅读了一些文件。正如你所说。但是,通常 wait() 函数用于互斥体,例如std::unique_lock<:mutex> ul(m_mutexTask); while (m_lTask​​.empty()) { m_condTask.wait(ul); } 。那么即使 notify_all() 唤醒所有线程,也只有一个线程可以锁定互斥锁,对吧?
    • 一次只有一个线程会锁定互斥锁,但一旦获得互斥锁,它们都会从wait返回。
    • @Yun:使用哪一个实际上取决于是否有任何等待线程可以处理正在等待的事情。如果有的话(例如,队列上有多个相同的阅读器),那么您使用 notify_one 因为这肯定更有效。如果有一个更复杂的条件,例如只有一个等待线程实际上可以在循环条件下成功,则您必须唤醒所有线程,因为您无法控制 notify_one 将唤醒哪个线程。
    • 如果只有一个等待线程,那么使用哪个线程没有区别。因此,您最好使用notify_all,以防您将来添加更多服务员——因为条件变量上的服务员可以无缘无故地唤醒,并且必须编写以正确处理它,添加额外的唤醒不会伤害其他也许比性能。而如果您使用notify_one,您可能会意外编写依赖于所选择的“正确”线程的代码。它可能看起来可以工作并且通过了你的所有测试,但是未来一些细微的变化会导致它停止工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-06-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多