gpt4 book ai didi

c++ - 我是否需要同步 std::condition_variable/condition_variable_any::notify_one

转载 作者:IT老高 更新时间:2023-10-28 22:28:10 25 4
gpt4 key购买 nike

是否需要同步std::condition_variable/condition_variable_any::notify_one

据我所知,如果丢失通知是可以接受的 - 可以调用未 protected notify_one(例如通过互斥锁)。

例如,我看到了以下使用模式(抱歉,不记得在哪里):

{
{
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);
}

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 的薄包装。

所以,问题:

  1. 对于 condition_variable_anycondition_variable 不使用互斥体保护 notify_one 是否是线程安全的?
  2. 为什么 condition_variable_any 的实现使用额外的互斥锁?
  3. 为什么 condition_variable_any::notify_onecondition_variable::notify_one 的实现不同?也许 condition_variable::notify_one 需要手动保护,但 condition_variable_any::notify_one 不需要?是 libstdc++ 错误吗?

最佳答案

I.e. it is just thin wrapper around condition_variable+mutex.

呃,不。仅仅因为它具有这些类型的成员并不能使它成为一个薄包装器。尝试了解它实际上做了什么,而不仅仅是它的私有(private)成员的类型。那里有一些非常微妙的代码。

  1. Is it thread-safe to not protect notify_one by mutex for either condition_variable_any or condition_variable?

是的。

实际上,在互斥锁被锁定的情况下调用notify_one()会导致等待线程被唤醒,尝试锁定互斥锁,发现它仍然被通知线程锁定,然后重新进入休眠状态直到互斥锁被释放。

如果您在没有锁定互斥锁的情况下调用 notify_one(),那么唤醒线程可以立即运行。

2 Why implementation of condition_variable_any uses additional mutex?

condition_variable_any 可以与任何 Lockable 类型一起使用,不仅仅是 std:mutex,而是在 libstdc++ 内部使用 condition_variable,它只能和std::mutex一起使用,所以它内部也有一个std::mutex对象。

所以 condition_variable_any 与两个互斥锁一起工作,一个由用户提供的外部互斥锁和一个由实现使用的内部互斥锁。

3 Why implementation of condition_variable_any::notify_one and condition_variable::notify_one differs? Maybe condition_variable::notify_one requires manual protection but condition_variable_any::notify_one doesn't? Is it libstdc++ bug?

不,这不是错误。

标准要求调用 wait(mx) 必须以原子方式解锁 mx 并休眠。 libstdc++ 使用内部互斥体来提供原子性保证。如果其他线程即将等待 condition_variable_any,则必须锁定内部互斥体以避免错过通知。

关于c++ - 我是否需要同步 std::condition_variable/condition_variable_any::notify_one,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15887306/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com