繁体   English   中英

布尔标志应该总是原子的吗?

[英]Should a boolean flag always be atomic?

假设有一个由主线程控制的布尔标志( keep_running )。 另一个线程无限循环,直到该标志变为false。

int main() {
    bool keep_running(true);
    std::thread run( [](bool &keep_running)
    {
        while(keep_running)
        {
            // do work
        }
    }, std::ref(keep_running) );

    // do other work
    keep_running = false;
    run.join();
    return 0;
}

该标志应该是原子的吗?

std::atomic<bool> keep_running

我想,非原子版本可能发生的最糟糕的情况是,当

while(keep_running)

被执行。 在这种情况下,循环将继续运行一次(并非绝对需要)迭代。 但就我而言,这是可以接受的。

上面的代码可能有错误的情况吗?

编辑:

出于性能原因(并且没有错误),我对此最感兴趣。 因此,对循环中的标志使用std :: atomic是否会对性能产生负面影响?

这只是C ++ 11标准,它禁止并发访问非原子变量(将它们标记为Undefined Behavior )。

因此,您需要将此变量声明为atomic。

请注意,对读取值使用keep_running.load(std::memory_order_relaxed) ,对写入值使用keep_running.store(true, std::memory_order_relaxed)将消除任何额外的性能开销,因此生成的代码将与没有原子的代码一样快。


我想,非原子版本可能发生的最糟糕的情况是该标志在当时被正确设置。

可能发生的情况是,在您的线程中,变量将被存储到寄存器中,并且永远不会被重新加载(因此,线程将永远不会停止)。 如果没有atomic或其他特殊类型和修饰符,则允许编译器执行此操作,而实际上是这样做的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM