Java在C中易变?

我知道在Java中使用volatile 。 那是(基于维基百科的文章 ):

对volatile变量的读写有一个全局排序。 这意味着访问volatile字段的每个线程将在继续之前读取其当前值,而不是(可能)使用缓存值。

我也知道在C中存在volatile关键字,但在完全不同的上下文中,主要用于内存映射I / O.

所以我想知道,是否有一些像Java在C中volatile构造? 哪个会阻止读取变量的缓存值?

如果它不存在于C中,是否有一个带有这样的结构的库,比如pthread

C中的volatile基本上是一个过时的,用于完全不同的场景,对multithreading编程没用。 由于某些原因,即使是最新的c ++标准也无法赋予它更多的意义,但却不得不发明一个新的关键字。

请注意,这意味着C标准所定义的volatile是无用的,编译器可能会给你额外的保证(我知道MS VC会这样做,我认为它提供了与java中volatile相同的保证),但这意味着程序被锁定为那个编译器。 大多数编译器也有一些内在函数来插入内存屏障,这更加明确,但本身又不可移植。

实际上,您可能最好使用一些更高级别的线程库来为工作提供合适的工具。 例如,POSIX为您提供低级别的内存屏障。

在c ++站点上,自0x11以来它更好 – 标准确实提供了std::atomic_thread_fence和primefaces变量。 请注意,c ++ 0x11内存模型与java版本不同,因此在移植时必须小心。

volatile的行为不一定不同; 它是不同的平台和背景。 您在问题中特别提到了内存映射设备。 如果你有一个内存映射设备,比如某些硬件可以翻转代码中由变量表示的寄存器,那么显然你想要一种方法来表明这一点。 如果不这样做,那么编译器将始终在假设唯一可以更改代码的系统是您的程序并且可能优化它的情况下工作。

一个很好的例子是,如果您在决策或控制流情况中使用变量。 如果这个变量永远不会直接在你的代码中操作,但可以被信号或一些内存映射硬件翻转,编译器可能会将决策条件优化为布尔值,因为它会假设值不会改变。 因此,当硬件翻转该值时,由于编译器优化,它不会反映在正在运行的代码中。

Java“缓存”基本上是相同的行为。 您的断开连接似乎来自这样一个事实,即您不是在C编译代码和Java是在虚拟机内部运行的JIT编译字节代码之间建立心理桥梁。 Java从Cinheritance其volatile性行为,但由于运行时上下文,此行为的后果完全不同。