4

我正在使用 linux,我有两个在另一个线程中读/写的变量。偶尔(100 毫秒)ThreadB 会读取变量的状态并执行一些操作。它基本上是一个while(1){ dosomething(); usleep(); }. 我担心变量会被缓存并且永远不会更新。

确保优化后循环正常工作的最佳方法是什么?我在想volatile应该做这项工作,但我听说它有时不起作用。两个循环都不经常运行(10ms+)。访问它们的最简单直接的方法是什么?我正在使用 C++11

我有点不确定如何使用std::atomic<int>. 我可以像普通的 int 变量一样使用它,它会按预期工作吗?

4

1 回答 1

5

您确实可以将其声明为std::atomic<int>,并且事情应该按照您的意愿工作。

volatile是关于保留生成的代码必须呈现给处理器以进行读/写的地址和值的序列。出于内存一致性的目的,它根本不限制硬件用它做什么,这是atomic. 这是英特尔的一篇文章,解释了这种差异。

C 和 C++ 标准(从 2011 年开始)定义了一个内存模型,该模型描述了根据语言定义或未定义的操作,以及如果整个程序定义良好,表达式可以产生哪些值。

根据标准,任何通过多个线程对单个对象(例如您的 shared int)进行非同步访问的程序,其中至少一次访问是写入,都是undefined。声明一个变量volatile不会使对它的访问同步。atomic根据定义,对声明为始终同步的变量的访问。

在默认情况下,如果您只使用atomic<int>而不更改任何其他有关如何使用它的内容,您将获得所谓的顺序一致访问,这是线程之间最强烈协调的,因此可能成本最高。对于您的用例,这似乎不是问题 - 成本大约为纳秒到微秒,而您以毫秒为单位进行轮询。如果您确实需要进一步优化,您可以指定限制较少的访问。

于 2015-06-20T18:34:29.363 回答