使用volatile作为primefaces

如果我有这样的东西……

volatile long something_global = 0; long some_public_func() { return something_global++; } 

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

注意:所有我使用它的原因是primefaces增量和减量 – 没什么比这更好的了。

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

后增量不是primefaces操作,它是内存访问,后跟内存写入。 交错两个意味着该值实际上只增加一次。

不,您必须使用依赖于平台的primefaces访问。 有几个库可以抽象这些 – GLib提供可移植的primefaces操作,如果需要可以回退到互斥锁,我相信Boost也提供了可移植的primefaces。

正如我最近所了解的 ,对于真正的primefaces访问,您需要一个完全内存屏障,而volatile不提供。 所有易失性保证是在每次访问时将重新读取存储器,并且不会重新排序对volatile存储器的访问。 优化器可以在易失性读/写之前或之后重新排序某些非易失性访问 – 可能在增量中间! – 所以你必须使用实际的primefaces操作。

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

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

我建议使用库。 简单的方法是在想要更新变量时锁定。 如果它们适合你正在做的事情,信号量可能会更快。 似乎GLib提供了一个相当有效的实现。

Windows提供InterlockedIncrement (和InterlockedDecrement )来执行您要求的操作。

Volatile只是阻止优化,但primefaces性需要更多。 在x86中,指令必须以LOCK前缀开头,在MIPS中,RMW循环必须由LL / SC构造包围,…

你的问题是C不保证增量运算符的primefaces性,实际上它们通常不是primefaces的。 您必须使用类似Windows API或编译器内置函数( GCC , MSVC )的库。