C中的volatile int和C ++ 0x的std :: atomic <int>一样好吗?</int>

时间:2011-07-08 16:37:12

标签: c c++11 atomic volatile

我需要在我的程序中使用原子变量。以前我使用std::atomic<int>,但我现在正在使用的平台没有支持C ++ 0x的g ++编译器。我使用了volatile int它似乎正在工作,因为我还没有在多核系统中遇到竞争条件我正在测试它。

我的问题是volatile int是否像<{1}}一样原子?此外,它是否会产生内存障碍(我也需要)?

7 个答案:

答案 0 :(得分:28)

没有。 volatile与多线程无关。它不会强制执行内存屏障(尽管某些编译器可能会选择添加无论如何),并且它不保证对非易失性对象进行读/写重新排序。

添加了

volatile以支持写入内存映射硬件I / O寄存器,在这种情况下,重要的是你的写入没有被优化掉,但没有精确的顺序保证wrt。需要非易失性读/写。

您可能还想阅读this

答案 1 :(得分:6)

易变变量并不意味着内存障碍,并且没有exchange的{​​{1}}或compare_exchange_*操作。它们确实避免了编译器在机器代码级别上将负载提升到多个负载(反之亦然,并且类似于商店),但就是这样。

您可能对这些文章感兴趣:

如果您没有std::atomic,则可能需要使用boost::atomic,或者使用您正在使用的任何编译器提供的低级屏障和原子操作原语。

答案 2 :(得分:4)

我见过你在一些评论中询问GCC,你走了。

GCC's Built-in functions for atomic memory access

答案 3 :(得分:1)

在C ++ 0x之前,该语言不是线程感知的,因此它不会阻止多次访问。宣布它不稳定将有所帮助,但它不会阻止比赛。

有关详细信息,请参阅http://en.wikipedia.org/wiki/Volatile_variable

要真正使操作成为原子,您需要使用线程库(win32线程,pthreads等)提供的任何锁定机制。

答案 4 :(得分:1)

来自Herb Sutter的差异here有一个很好的总结。总结(剪切和粘贴):

  

安全地编写无锁代码   线程之间没有通信   使用锁,更喜欢使用有序   原子变量:Java / .NET volatile,   C ++ 0x原子,与C兼容   atomic_T。

     

安全地与特殊沟通   硬件或其他内存   不寻常的语义,使用不可优化   变量:ISO C / C ++ volatile。   记住读写   这些变量不一定   然而,原子。

答案 5 :(得分:1)

volatile基本上告诉编译器它不能对特定内存位置的内容做出假设。例如

bool test = true;
while(!test)
{
    /* do something (e.g. wait) */
}

编译器可能会优化整个while,因为它假定test始终为真。但是,如果test在某个时刻将从其他地方(例如某些硬件或其他线程)更新,我们不希望编译器假设它知道test中的内容。我们可以告诉编译器使用volatile

正如其他答案所说,它无法保证在什么顺序访问内存位置。

P.S。我无耻地从某个地方偷走了这个例子,但不记得我在哪里看到它。

答案 6 :(得分:0)