【问题标题】:Is it ok to use atomic<bool> for multiple thread synchronize than event是否可以使用 atomic<bool> 进行多线程同步而不是事件
【发布时间】:2014-02-20 02:49:50
【问题描述】:

就像在 C++11 中一样,它是原子导入的,正如您在我们的旧代码中知道的那样,它使用 windows 事件 (CreateEvent/SetEvent) 进行线程同步。伪代码如下。

线程 A:

while(true)
{
    if(check event is set)
       break;
    else
       do stuff
}

线程 B:

SetEvent() //ask thread A stop.

我想知道是否在这种情况下。可以使用下面更简单的 atomic 吗,有什么 atomic bool 不能代替 event 吗?提前致谢!

std::atomic<bool> bFlag = false;

线程 A:

while(true)
{
    if(bFlag)
       break;
    else
       do stuff
}

线程 B:

bFlag = true;

[更新]

为了让问题更清楚,线程A不会写bFlag,它只是读取它来知道何时退出线程。线程B会写bFlag通知线程A停止。

解决方案中没有性能考虑。

【问题讨论】:

    标签: windows multithreading events c++11 atomic


    【解决方案1】:

    这样做可能是精心设计的解决方案的一部分。您需要注意不太明显的竞争条件和 ABA 问题(如果“do stuff”使用 bFlag)。

    在下文中,当我说“坏”时,我的意思是“两个线程可以同时读/写或写/写相同的数据吗?”。

    如果“do stuff”在 bFlag 设置为 true 几纳秒后开始执行,会不会很糟糕?
    哪些情况会导致 bFlag 再次变为 false?
    如果“do stuff”在 bFlag 变为 false 后仅几纳秒内没有运行,会不会很糟糕?
    如果程序在 bFlag 设置为 false 之前多次运行“do stuff”是不是很糟糕?

    如果您能正确回答这些问题,则没有技术原因您不能这样做,但这可能是一种简单的方法。

    在大多数情况下,std::atomic 是使用原子比较和交换 (CAS) (http://en.wikipedia.org/wiki/Compare-and-swap)CPU 指令实现的,MESI 协议 (http://en.wikipedia.org/wiki/MESI_protocol) 将确保缓存一致性。不过,我认为没有任何东西可以阻止使用操作系统级别的互斥锁来实现这一点。如果这不是性能瓶颈或性能不是主要问题,那么在 bFlag 周围使用互斥体并“做一些事情”可能会更容易。

    另一种可能的途径是使用 std::futures 从线程 B 异步“做事”。使用它,您可以将“做事”视为自己的功能,而无需担心线程的血腥细节。 (http://en.cppreference.com/w/cpp/thread/future)

    ** 编辑 ** 我不知道您所说的事件是指特定于 Windows 的事件。我的回答仍然适用于一般情况,但由于我不知道 windows SetEvent 的细节,它的语义几乎可以改变任何东西。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-30
      • 2014-03-23
      • 1970-01-01
      • 2011-02-19
      • 2021-09-09
      • 2015-07-14
      • 1970-01-01
      • 2013-04-25
      相关资源
      最近更新 更多