首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用volatile long作为原子

使用volatile long作为原子
EN

Stack Overflow用户
提问于 2010-06-26 09:48:51
回答 6查看 2.1K关注 0票数 4

如果我有这样的东西...

代码语言:javascript
复制
volatile long something_global = 0;

long some_public_func()
{
    return something_global++;
}

当使用多个线程访问时,期望这段代码不会中断(竞争条件)是否合理?如果它不是标准的,那么它仍然可以作为现代编译器的合理假设吗?

注意:我使用它的唯一目的是原子递增和递减--没有更花哨的东西。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2010-06-26 09:52:16

无易失性并不意味着已同步。它只是意味着每次访问都将返回最新的值(而不是线程中本地缓存的副本)。

后增量不是原子操作,它是内存访问,然后是内存写入。交错两个可能意味着该值实际上只递增一次。

票数 16
EN

Stack Overflow用户

发布于 2010-06-26 10:03:42

不,您必须使用与平台相关的原子访问。有几个库对这些进行了抽象-- GLib提供了可移植的原子操作,如果需要,这些操作可以回退到互斥锁,我相信Boost也提供了可移植的原子。

作为我的recently learned,对于真正的原子访问,你需要一个volatile没有提供的完整的内存屏障。所有易失性保证是存储器将在每次访问时被重新读取,并且对volatile存储器的访问将不会被重新排序。优化器可以在易失性读/写之前或之后对某些非易失性访问进行重新排序--可能是在递增过程中!--因此必须使用实际的原子操作。

票数 4
EN

Stack Overflow用户

发布于 2010-06-26 10:00:59

在现代快速多核处理器上,由于缓存和写缓冲区,原子指令的开销很大。

因此,编译器不会仅仅因为添加了volatile关键字就发出原子指令。您需要求助于内联汇编或编译器特定的扩展(例如gcc atomic builtins)。

我推荐使用库。最简单的方法是,当您想要更新变量时,只使用一个锁。如果信号量适合于您正在做的事情,那么它们可能会更快。看起来GLib提供了一个相当高效的实现。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3122382

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档