我需要同步std::condition_variable/condition_variable_any::notify_one
?我需要同步的std :: condition_variable/condition_variable_any :: notify_one
至于我可以看到,如果丢失的通知是可以接受的 - 这是确定调用notify_one
不受保护(mutex所为例)。
举例来说,我看到了下面的使用模式(抱歉,不记得在哪里):
{
{
lock_guard<mutex> l(m);
// do work
}
c.notify_one();
}
但是,我考察的libstdC++源代码,我看到:
condition_variable::notify_one
void condition_variable::notify_one() noexcept
{
int __e = __gthread_cond_signal(&_M_cond);
// XXX not in spec
// EINVAL
if (__e)
__throw_system_error(__e);
}
and condition_variable_any::notify_one:
void condition_variable_any::notify_one() noexcept
{
lock_guard<mutex> __lock(_M_mutex);
_M_cond.notify_one();
}
这里是condition_variable_any的布局:
class condition_variable_any
{
condition_variable _M_cond;
mutex _M_mutex;
// data end
即它只是在condition_variable + mutex周围的薄包装。
所以,问题:
- 它是线程安全的,不会被用于互斥或者
condition_variable_any
或condition_variable
保护notify_one
? - 为什么condition_variable_any的实现使用额外的互斥量?
- 为什么实施
condition_variable_any::notify_one
和condition_variable::notify_one
有所不同?可能condition_variable::notify_one
需要手动保护,但condition_variable_any::notify_one
不需要?它是libstdC++的错误?
谢谢!这帮助了我很多。特别回答2和3 - 关于原子性的好处,以及无论如何都使用互斥体的内部元素。顺便说一句,您可以添加指向pthread_cond_wait http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_wait.html的链接,以显示最常见的实现仅适用于内部中它自己的互斥体。你能否澄清一下你的意思是“这里有一些非常微妙的代码”。 – qble 2013-04-09 20:31:33
关于1. - 可否锁定condition_variable :: notify_one导致错过通知?即线程#1在互斥体中执行任务,发送结果,解锁互斥体,[同时]线程#2锁定互斥体但尚未调用wait,[同时]线程#1调用notify_one,[同时]线程#2调用wait - 通知丢失。 – qble 2013-04-09 20:37:04
这不是一个丢失的通知,这是等待线程在等待之前不检查条件谓词。锁定互斥锁并不能解决这种情况,通知仍可能在等待线程锁定互斥锁之前发生。您**必须在等待条件变量时检查关联的谓词 – 2013-04-10 00:27:24