我正在使用Linux,我有两个变量在另一个线程中读/写。偶尔(100ms)ThreadB 会读取变量的状态并执行某些操作。这基本上是一个while(1){ dosomething(); usleep(); }
.我担心变量会被缓存并且永远不会更新。
确保循环在优化后正常工作的最佳方法是什么?我想volatile
应该做这项工作,但我听说它有时不起作用。两个循环都不频繁运行 (10ms+)。访问它们的最简单、最直接的方法是什么?我正在使用 C++11
我有点不确定如何使用std::atomic<int>
.我可以像普通的 int 变量一样使用它并且它会按预期工作吗?
你确实可以将其声明为 std::atomic<int>
,事情应该按照你想要的方式工作。
volatile
是关于保留生成的代码必须呈现给处理器以进行读取/写入的地址和值序列。它完全不限制硬件出于内存一致性的目的而对其执行的操作,这是atomic
关注的问题。这是英特尔的一篇文章,解释了这种差异。
C 和 C++ 标准(从 2011 年开始)定义了一个内存模型,该模型描述了根据语言定义或未定义的操作,以及如果程序作为一个整体定义良好,表达式可以产生哪些值。
根据标准,任何由多个线程对单个对象(例如您的共享int
)进行不同步访问的程序都是未定义的,其中至少一次访问是写入。声明变量volatile
不会同步对它的访问。根据定义,对声明为 atomic
的变量的访问始终是同步的。
在默认情况下,如果您只使用atomic<int>
而不更改有关其使用方式的任何其他内容,您将获得所谓的顺序一致访问,这是线程之间协调最强的访问,因此可能成本最高。对于您的用例,这似乎不是一个问题 - 成本在纳秒到微秒的数量级,而您以毫秒为单位轮询。如果确实需要进一步优化,则可以指定限制较少的访问。