本文介绍了我需要同步std :: condition_variable / condition_variable_any :: notify_one的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要同步 std :: condition_variable / condition_variable_any :: notify_one

可以看到,如果丢失通知是可以接受的 - 可以调用 notify_one 不受保护(例如mutex)。

As far as I can see, if lost of notifications is acceptable - it is OK to call notify_one not protected (by mutex for example).

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

For instance, I saw following usage patterns (sorry, don't remember where):

{
    {
        lock_guard<mutex> l(m);
        // do work
    }
    c.notify_one();
}






但是,我检查了libstdc ++来源,我看到:


But, I inspected libstdc++ sources, and I see:

void condition_variable::notify_one() noexcept
{
    int __e = __gthread_cond_signal(&_M_cond);
    // XXX not in spec
    // EINVAL
    if (__e)
        __throw_system_error(__e);
}

和:

void condition_variable_any::notify_one() noexcept
{
    lock_guard<mutex> __lock(_M_mutex);
    _M_cond.notify_one();
}

这里是condition_variable_any的布局:

And here is layout of condition_variable_any:

class condition_variable_any
{
    condition_variable _M_cond;
    mutex _M_mutex;
    // data end

所以,问题:


  1. >通过mutex为 condition_variable_any condition_variable不能保护 notify_one / code>?

  2. 为什么condition_variable_any的实现使用额外的互斥?

  3. 为什么实现 condition_variable_any :: notify_one condition_variable :: notify_one 不同?可能 condition_variable :: notify_one 需要手动保护,但 condition_variable_any :: notify_one 不会?是libstdc ++错误吗?

  1. Is it thread-safe to not protect notify_one by mutex for either condition_variable_any or condition_variable?
  2. Why implementation of condition_variable_any uses additional mutex?
  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?


推荐答案

Er,no。只是因为它有那些类型的成员不会使它是一个薄包装。尝试了解它实际上是什么,不只是它的私人成员的类型。

Er, no. Just because it has members of those types doesn't make it a thin wrapper. Try to understand what it actually does, not just the types of its private members. There's some quite subtle code there.


  1. 它是线程安全的,无法通过互斥锁保护notify_one condition_variable_any或condition_variable?


可以。

事实上,调用 notify_one()并锁定互斥锁将导致等待线程被唤醒,尝试锁定互斥锁,发现它仍然被通知线程锁定,回到睡眠状态,直到互斥体释放。

In fact, calling notify_one() with the mutex locked will cause waiting threads to wake up, attempt to lock the mutex, find it is still locked by the notifying thread, and go back to sleep until the mutex is released.

如果调用 notify_one()而不锁定互斥锁,则唤醒线程可以立即运行。

If you call notify_one() without the mutex locked then the waking threads can run immediately.

condition_variable_any 可用于任何可锁定类型,而不仅仅是 std:mutex libstdc ++中的一个使用 condition_variable ,它只能与 std :: mutex 一起使用, std :: mutex 对象。

condition_variable_any can be used with any Lockable type, not just std:mutex, but internally the one in libstdc++ uses a condition_variable, which can only be used with std::mutex, so it has an internal std::mutex object too.

所以 condition_variable_any

不,这不是错误。

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

The standard requires that calling wait(mx) must atomically unlock mx and sleep. libstdc++ uses the internal mutex to provide that guarantee of atomicity. The internal mutex must be locked to avoid missed notifications if other threads are just about to wait on the condition_variable_any.

这篇关于我需要同步std :: condition_variable / condition_variable_any :: notify_one的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-14 07:38