Java在C中易失吗?

Java's volatile in C?

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

There is a global ordering on the reads and writes to a volatile
variable. This implies that every thread accessing a volatile field
will read its current value before continuing, instead of
(potentially) using a cached value.

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

所以我想知道,在C中是否存在像Java的volatile这样的结构?这将防止
读取变量的缓存值?

如果C中不存在它,也许是否有一个具有这样构造的库,例如pthread


在C语言中,

volatile基本上是一种过时,旨在用于完全不同的场景,并且对多线程编程没有用处。出于某种原因,甚至最新的c标准也无法赋予它更多的含义,而是不得不发明一个新的关键字。

提醒您,这意味着C标准所定义的volatile是无用的,编译器可能会为您提供其他保证(我知道MS VC可以提供,并且我认为它与Java中的volatile提供的保证基本相同),但这意味着该程序被锁定到该编译器。大多数编译器还具有一些用于插入内存屏障的内在函数,这些内在函数更加明确,但本质上也无法移植。

实际上,您最好使用一些更高级别的线程库,该库为该工作提供正确的工具。例如。 POSIX为您提供了低级内存屏障afaik。

在c站点上,最好使用0x11-标准确实提供了std::atomic_thread_fence和原子变量。请注意,尽管c 0x11内存模型与Java内存模型并不相同,所以在移植时必须要小心。


volatile的行为不一定是不同的;平台和上下文是不同的。您在问题中特别提到了内存映射设备。如果您有一个内存映射的设备(例如某些硬件)可以翻转代码中由变量表示的寄存器,那么显然您需要一种方式来表明这一点。如果您不这样做,则编译器将始终在这样的假设下工作,即唯一可以更改代码的系统就是您的程序,并且可以对其进行优化。

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

Java " caches "基本上是相同的行为。断开连接的原因似乎是您没有在虚拟机内部运行的C语言和Java JIT字节代码之间架起一座桥梁。 Java从C继承其volatile行为,但是由于运行时上下文,此行为的后果完全不同。