c++ - bool 标志应该始终是原子的吗?

标签 c++ multithreading c++11 atomic

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

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 标准禁止(将它们标记为未定义行为)并发访问非原子变量。

所以你需要声明这个变量是原子的。

请注意,使用 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.

在您的线程中,变量可能会被存储到寄存器中并且永远不会被重新加载(因此线程永远不会停止)。在没有 atomic 或其他特殊类型和修饰符的情况下,编译器可以这样做,而且它确实这样做了。

关于c++ - bool 标志应该始终是原子的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34898201/

相关文章:

c++ - 用于 cout 顺序的 OpenMP 并行

数百万次执行后的 C++ 程序稳定性

asp.net - nHibernate 使用 Log4Net 进行日志记录,线程 session 问题

c++ - 如何测试是否存在模板函数特化

c++ - 如何在编译时选择可能的选项来确定函数的返回值

c++ - 无法追踪 Qt 程序崩溃的原因

c++ - 加载 Rcpp 模块

python - concurrent.futures 与 Python 中的多处理相比有哪些优势?

c++ - 如何在 makefile 中设置编译标志?

c++ - 返回指向 vector 元素的指针