在boost::condition_variable的源代码中,condition_variable::notify_one()方法试图使用pthread_cond_signal()唤醒一个线程。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只唤醒一个线程呢?
发布于 2020-07-22 12:07:46
那么,为什么boost::condition_variable确保pthread_cond_signal只唤醒一个线程呢?
为什么?这个问题是没有意义的。问题是“是否”。但事实并非如此(如你所见)。
您可以看到,它使用那里的pthread来解除(至少是一个等待线程的)的阻塞。
这与使用notify_all的pthread_cond_broadcast完全相反。
这种区别是有用的,因为它可以提高并发操作的效率,在这样的情况下,唤醒所有的服务员将是浪费的。
关联:在使用条件变量时,必须始终考虑到假醒。
发布于 2020-07-22 21:47:34
您似乎是在询问boost::condition_variable::notify_one()的名称,因为基于线程的实现实际上可能会唤醒多个线程。
事实是,尽管pthread_cond_signal()的规范说,它将解除“至少一个”线程阻塞在简历(只要有),这是愚蠢的标准说话。虽然允许pthread_cond_signal()解除阻塞多个线程,但通常情况下,如果在CV上有任何线程在发出信号时被阻塞,那么就会有一个线程被解除阻塞。允许一个以上的不阻塞允许实现更轻量级和更高效,并且它没有给程序员带来新的负担,因为处理虚假唤醒的相同措施应该对额外的唤醒同样有效,假设您甚至选择区分它们。
因此,boost::condition_variable::notify_one()之所以如此命名,是因为"notify_one“准确地表示了程序员有时会想要的一种行为,而所谓的方法是他们请求它的方式。有时候,它提供了一些不同的东西,这是非常广泛的功能的一个特点。试图捕捉名称中的所有细节是没有帮助的。您不仅会以不可读的长名称(如notify_at_least_one_if_any_are_waiting )结束,而且您将失去对函数行为的主要期望。
https://stackoverflow.com/questions/63030760
复制相似问题