Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java';在C中是挥发性的吗?_Java_C_Multithreading_Pthreads_Volatile - Fatal编程技术网

Java';在C中是挥发性的吗?

Java';在C中是挥发性的吗?,java,c,multithreading,pthreads,volatile,Java,C,Multithreading,Pthreads,Volatile,我知道Java中使用了volatile。 也就是说(基于: 对volatile的读写操作有一个全局排序 变量这意味着每个线程访问一个volatile字段 将在继续之前读取其当前值,而不是 (可能)使用缓存的值 我也知道C语言中存在volatile关键字,但它的上下文完全不同,主要用于内存映射I/O 所以我想知道,在C语言中是否有类似Java的volatile的结构?这将阻止 读取变量的缓存值 如果它在C中不存在,是否有这样一个库,比如pthread?volatile在C中基本上是一个时代错误,它

我知道Java中使用了
volatile
。 也就是说(基于:

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

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

所以我想知道,在C语言中是否有类似Java的
volatile
的结构?这将阻止 读取变量的缓存值


如果它在C中不存在,是否有这样一个库,比如
pthread

volatile
在C中基本上是一个时代错误,它是为一个完全不同的场景而设计的,对多线程编程没有用处。由于某些原因,甚至最新的C++标准也不能赋予它更多的意义,而不得不创造一个新的关键字。 请注意,这意味着C标准定义的
volatile
是无用的,编译器可能会为您提供额外的保证(我知道MS VC提供了,我认为它提供的保证与java中volatile的基本相同),但这意味着程序被锁定在一个编译器上。大多数编译器也有一些内部函数来插入内存屏障,这有点显式,但本身并不可移植

在实践中,您可能最好使用更高级别的线程库,为该工作提供合适的工具。例如,POSIX为您提供了低级别的存储屏障


<0>从0x11开始,C++的站点更好了——标准提供了代码> STD::AddiICTythRead Save和原子变量。请注意,虽然c++0x11内存模型与java内存模型不同,但在移植时必须小心。

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

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


Java“缓存”基本上是相同的行为。您的脱节似乎来自这样一个事实,即您没有在虚拟机内部运行的C编译代码和Java JIT编译字节代码之间建立心理桥梁。Java从C继承了它的
volatile
行为,但由于运行时上下文的不同,这种行为的后果有很大的不同。

您希望内存障碍来排序读/写,但它们是特定于平台的,不是C@awoodland我不希望我的所有线程在继续之前在某个特定点上互相等待。据我所知,这就是记忆障碍的作用。我只是想在读取变量时,确保读取的是该变量的最新值,而不是缓存的值。@Fooko你在想一些不同的东西。内存屏障基本上是CPU的低级指令。Java的
volatile
是用内存屏障实现的,对此有很好的讨论barriers@awoodland很好的链接。好的,可以理解的总结。谢谢你的回答。据我所知,屏障/围栏是一个不同的概念,正如我已经对阿伍德兰德说过的。我认为屏障是用来让所有线程在一个特定点等待所有其他线程,然后再继续工作的。我不想让我的线程等待其他线程,我只想让它们读取的所有内容都与当时内存中存在的内容一致,而不是缓存的值一致。当然,我也不想重新排序,但我仍然不明白屏障在这方面有什么帮助?@Fooko在这里看到了awoodlands和我对你观点的回答。你似乎想到了Java的CyclicBarrier。一个是极低级别的概念,另一个是大多数线程库提供的相当高级别的构造。简单地解释了基本原理,但是awoodlands链接乍一看似乎非常好。@Fooko R:内存栅栏/屏障不是线程屏障。内存围栏是一种特殊指令,它不允许针对围栏本身对加载或存储或两者进行重新排序。因此,实际上,围栏之前的负载不能与围栏之后的负载重新排序。好的,我将阅读wiki文章和awoodlands链接。谢谢@都铎王朝,但似乎我应该在每次读写程序后使用围栏。例如,
read/fence/write/fence/read/fence/read/fence/现在我不想使用任何重新排序,难道没有更简单的方法让编译器(+硬件)使用吗?看来C11内存模型与C++11内存模型基本相同。