简体   繁体   English

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

[英]Should a boolean flag always be atomic?

Suppose there is a boolean flag ( keep_running ) which is controlled by the main thread. 假设有一个由主线程控制的布尔标志( keep_running )。 Another thread loops indefinitely until this flag becomes false. 另一个线程无限循环,直到该标志变为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;
}

Should that flag be atomic? 该标志应该是原子的吗?

std::atomic<bool> keep_running

I imagine, the worst which can happen to the non-atomic version would be that the flag gets set right at the time when the 我想,非原子版本可能发生的最糟糕的情况是,当

while(keep_running)

is executed. 被执行。 In which case, the loop keeps running for one more (not strictly needed) iteration. 在这种情况下,循环将继续运行一次(并非绝对需要)迭代。 But in my case, this would be acceptable. 但就我而言,这是可以接受的。

Is there a possible scenario where the above code could be wrong? 上面的代码可能有错误的情况吗?

EDIT: 编辑:

I'm mostly interested in this for performance reasons (and for not having bugs). 出于性能原因(并且没有错误),我对此最感兴趣。 Thus, would the use of std::atomic for the flag in the loop negatively impact performance? 因此,对循环中的标志使用std :: atomic是否会对性能产生负面影响?

It is just C++11 standard which forbids (mark them as Undefined Behaviour ) concurrent accesses to non-atomic variable. 这只是C ++ 11标准,它禁止并发访问非原子变量(将它们标记为Undefined Behavior )。

So you need to declare this variable atomic. 因此,您需要将此变量声明为atomic。

Note, that using keep_running.load(std::memory_order_relaxed) for read value and keep_running.store(true, std::memory_order_relaxed) for write value will eliminate any additional perfomance costs, so resulted code will be as faster as one without atomic. 请注意,对读取值使用keep_running.load(std::memory_order_relaxed) ,对写入值使用keep_running.store(true, std::memory_order_relaxed)将消除任何额外的性能开销,因此生成的代码将与没有原子的代码一样快。


I imagine, the worst which can happen to the non-atomic version would be that the flag gets set right at the time. 我想,非原子版本可能发生的最糟糕的情况是该标志在当时被正确设置。

It can be happen that in your thread the variable will be stored into register and never be reloaded (so thread will never be stopped). 可能发生的情况是,在您的线程中,变量将被存储到寄存器中,并且永远不会被重新加载(因此,线程将永远不会停止)。 Without atomic or other special type and modifiers compiler is allowed to do that, and it actually does. 如果没有atomic或其他特殊类型和修饰符,则允许编译器执行此操作,而实际上是这样做的。

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

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