【问题标题】:Why boost::condition_variable can use pthread_cond_signal to wake up only one thread为什么 boost::condition_variable 可以使用 pthread_cond_signal 只唤醒一个线程
【发布时间】:2020-07-22 09:10:53
【问题描述】:

在 boost::condition_variable 的源码中,方法 condition_variable::notify_one() 尝试使用 pthread_cond_signal() 只唤醒一个线程。 https://code.woboq.org/appleseed/include/boost/thread/pthread/condition_variable.hpp.html

inline void condition_variable::notify_one() BOOST_NOEXCEPT
    {
#if defined BOOST_THREAD_PROVIDES_INTERRUPTIONS
        boost::pthread::pthread_mutex_scoped_lock internal_lock(&internal_mutex);
#endif
        BOOST_VERIFY(!pthread_cond_signal(&cond));
    }

但是,POSIX 说:

pthread_cond_signal() 函数应至少解除阻塞在指定条件变量 cond 上阻塞的线程之一(如果任何线程在 cond 上阻塞)。

那么为什么 boost::condition_variable 确保 pthread_cond_signal 只唤醒一个线程???

【问题讨论】:

    标签: c++ unix boost pthreads


    【解决方案1】:

    那么为什么 boost::condition_variable 确保 pthread_cond_signal 只唤醒一个线程???

    为什么?这个问题没有实际意义。问题是“是否”。它没有(如你所见)。

    您可以看到它在那里使用 pthread API 来解除阻塞至少一个等待线程。

    这只是与使用pthread_cond_broadcastnotify_all 相对。

    这种区别很有用,因为它可以在唤醒所有服务员很浪费的情况下提高并发操作的效率。

    相关:使用条件变量时,必须始终考虑spurious wake-up

    【讨论】:

      【解决方案2】:

      您似乎在询问boost::condition_variable::notify_one()名称,因为基于 pthread 的实现实际上可能会唤醒多个线程。

      事实上,尽管pthread_cond_signal() 的规范说它将解除阻塞在 CV 上的“至少一个”线程阻塞(如果有的话),那是狡猾的标准说法。虽然允许pthread_cond_signal() 解除对多个线程的阻塞,但通常和预期的是,如果在发出信号时,CV 上有任何线程被阻塞,那么只有一个线程会被解除阻塞。允许多个不阻塞允许实现更轻量级和更高效,并且它不会给程序员带来新的负担,因为处理 spurious 唤醒的相同措施应该同样有效地对抗 额外的唤醒,假设您甚至选择区分它们。

      因此,boost::condition_variable::notify_one() 之所以如此命名,是因为“notify_one”准确地表示了程序员有时会想要的一种行为,而所谓的方法是他们请求它的方式。偶尔它会提供一些不同的东西是非常广泛的功能的一个特征。尝试捕获名称中的所有细节是没有帮助的。您不仅会得到难以阅读的长名称,例如 notify_at_least_one_if_any_are_waiting,而且您会失去对函数行为的主要期望意义。

      【讨论】:

      • 所以你的意思是虽然函数名是'notify_one',但实际上它可能通知多个线程,其行为将与'pthread_cond_signal'相同?
      • 或多或少,@xuhaoee。完全有理由认为它会尝试唤醒一个在 CV 上等待的线程,但在任何给定的平台上可能都不可能确保不超过一个解除阻塞。这是许多现实世界的 CV 实现的一个特点,它确实与 pthread_cond_signal 的行为相同。
      猜你喜欢
      • 2019-12-04
      • 2011-06-07
      • 2020-11-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-02
      相关资源
      最近更新 更多