C 中的 volatile int 与 std::atomic一样好吗? C++0x 的?

发布于 2024-11-19 06:42:41 字数 269 浏览 3 评论 0原文

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

我的问题是 volatile int 是否像 std::atomic 一样atomic?另外,它是否会产生内存障碍(我也需要)?

I need to have atomic variables in my program. Previously I was using std::atomic<int>, but the platform in which I'm working now does not have a g++ compiler that supports C++0x. I used volatile int and it seems to be working, as I haven't experienced a race condition yet in the multicore system I'm testing it on.

My question is if volatile int is atomic like std::atomic<int>? Also, does it creates memory barriers (which I also require)?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

佞臣 2024-11-26 06:42:42

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

添加了 易失性 来支持写入内存映射的硬件 I/O 寄存器,在这种情况下,重要的是您的写入不会被优化,但没有精确的顺序保证。需要非易失性读/写。

您可能还想阅读 这个

No. volatile has nothing to do with multithreading. It doesn't enforce a memory barrier (although some compilers might choose to add that anyway), and it makes no guarantees about read/write reordering with respect to non-volatile objects.

volatile was added to support writing to memory-mapped hardware I/O registers, and such cases, where it is important that your write isn't optimized away, but no precise ordering guarantees wrt. non-volatile reads/wrties are required.

You might also want to read this

蛮可爱 2024-11-26 06:42:42

易失性变量并不意味着内存屏障,并且没有 std::atomicexchangecompare_exchange_* 操作。它们确实避免了编译器在机器代码级别将一个负载提升为多个负载(反之亦然,对于存储也类似),但仅此而已。

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

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

Volatile variables do NOT imply memory barriers, and do not have the exchange or compare_exchange_* operations of std::atomic. They do avoid the compiler lifting a load into multiple loads on the machine code level (and vice versa, and similar for stores) but that's it.

You may be interested in these articles:

If you do not have std::atomic, you may want to use boost::atomic, or use the low-level barrier and atomic-operation primitives offered by whatever compiler you're using.

画尸师 2024-11-26 06:42:42

我看到你在一些评论中询问 GCC,就在这里。

GCC 用于原子内存访问的内置函数

I've seen you asking about GCC in some comments, here you go.

GCC's Built-in functions for atomic memory access

昔梦 2024-11-26 06:42:42

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

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

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

正如其他答案所说,它不能保证事物访问内存位置的顺序。Ps

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

volatile basically tells the compiler it can't make assumptions about what is in a particular memory location. For instance

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

the compiler might optimize away the whole while because it assumes test is always true. If however test is at some point going to be updated from elsewhere (some hardware or another thread for instance) the we do not want the compiler to assume it knows what is in test. We can tell the compiler that using volatile.

As the other answers say, it gives no guarantees about what order things access the memory location in.

P.s. I shamelessly stole that example from somewhere but can't remember where I saw it.

゛清羽墨安 2024-11-26 06:42:42

在 C++0x 之前,该语言不支持线程,因此它不会阻止多重访问。声明它是不稳定的会对一些人有所帮助,但它不会阻止竞争。

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

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

Before C++0x, the language wasn't thread aware, so it did not prevent multiple access. Declaring it volatile will help some, but it won't prevent races.

See http://en.wikipedia.org/wiki/Volatile_variable for more details.

To truly make operations atomic, you'll need to employ whatever locking mechanism your threading library (win32 threads, pthreads, etc) provides.

乱世争霸 2024-11-26 06:42:42

Herb Sutter 在此处对差异进行了很好的总结。总结(剪切和粘贴):

安全地编写无锁代码
线程之间进行通信,无需
使用锁,更喜欢使用有序的
原子变量:Java/.NET 易失性,
C++0x 原子性,与 C 兼容
原子_T。

与特殊人员安全通信
硬件或其他内存
不寻常的语义,使用不可优化的
变量:ISO C/C++ 易失性。
请记住,读取和写入
这些变量不一定
然而,原子。

There's a good summary of the diffs here, from Herb Sutter. In summary (cut and paste):

To safely write lock-free code that
communicates between threads without
using locks, prefer to use ordered
atomic variables: Java/.NET volatile,
C++0x atomic, and C-compatible
atomic_T.

To safely communicate with special
hardware or other memory that has
unusual semantics, use unoptimizable
variables: ISO C/C++ volatile.
Remember that reads and writes of
these variables are not necessarily
atomic, however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文