std :: condition_variable的notify_all()和notify_one()有什么区别?

Yun*_*ang 36 c++ multithreading condition-variable c++11

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

GMa*_*ckG 31

例如,如果条件变量上有十个线程被阻塞,则notify_one()只会取消阻塞一个线程,同时notify_all()将全部解除阻塞.在您的情况下,您将要使用,notify_one()因此您不会唤醒没有任何工作等待它们的线程.

  • @Yun:使用哪一个取决于是否有任何等待的线程可以处理正在等待的东西.如果有的话(例如,队列中有多个相同的读者),那么你使用notify_one,因为它肯定更有效.如果有一个更复杂的条件,只有一个等待线程实际上可以成功循环条件,你必须唤醒所有这些,因为你无法控制notify_one将唤醒哪个线程. (15认同)
  • 如果只有一个等待线程,那么你使用它没有任何区别.所以你不妨使用`notify_all`以防你将来添加更多的服务员 - 因为条件变量上的服务员可以无缘无故地醒来,并且必须写入以正确处理,添加额外的唤醒不会伤害其他而不是表现.而如果你使用`notify_one`,你可能会意外地编写依赖于所选"正确"线程的代码.它似乎可以工作并通过所有测试,但是将来一些微妙的变化会导致它停止工作. (8认同)
  • 一次只有一个线程会锁定互斥锁,但是一旦它们获得互斥锁,它们都会从`wait`返回. (7认同)
  • 谢谢,G曼。我从互联网上阅读了一些文档。正如你所说。然而,通常 wait() 函数用于互斥体,例如 std::unique_lock<std::mutex> ul(m_mutexTask); while (m_lTask​​.empty()) { m_condTask.wait(ul); }。那么即使notify_all()唤醒所有线程,也只有一个线程可以锁定互斥体,对吧? (3认同)