Questions tagged «volatile»

易失性是用于定义“可以自行更改”的数据存储区域(对象,字段,变量,参数)的限定符,因此无法进行某些代码生成器优化。在某些但不是全部识别该限定符的语言中,对此类数据的访问是线程安全的。

8
.NET中双重检查锁定中对volatile修饰符的需求
多篇文章说,在.NET中实施双重检查锁定时,您要锁定的字段应应用volatile修饰符。但是为什么呢?考虑以下示例: public sealed class Singleton { private static volatile Singleton instance; private static object syncRoot = new Object(); private Singleton() {} public static Singleton Instance { get { if (instance == null) { lock (syncRoot) { if (instance == null) instance = new Singleton(); } } return instance; } } …
85 c#  singleton  volatile 

6
允许编译器优化掉局部volatile变量吗?
是否允许编译器对此进行优化(根据C ++ 17标准): int fn() { volatile int x = 0; return x; } 对此吗? int fn() { return 0; } 如果是,为什么?如果没有,为什么不呢? 关于此主题的一些思考:当前的编译器将其编译fn()为放置在堆栈中的局部变量,然后将其返回。例如,在x86-64上,gcc创建以下代码: mov DWORD PTR [rsp-0x4],0x0 // this is x mov eax,DWORD PTR [rsp-0x4] // eax is the return register ret 现在,据我所知,标准并没有说应该将局部volatile变量放入堆栈中。因此,此版本同样不错: mov edx,0x0 // this is x mov …

3
为什么指向“易失性”的指针(例如“ volatile int * p”)有用?
volatile告诉编译器不要优化引用,以便每次读/写操作都不会使用寄存器中存储的值,而是进行真正的内存访问。我可以理解它对于某些普通变量很有用,但不了解它如何volatile影响指针。 volatile int *p = some_addr; int a = *p; // CPU always has to load the address, then does a memory access anyway, right? 如果声明为,有什么区别int *p = some_addr?
77 c  pointers  volatile 

12
Java中volatile关键字的最简单易懂的示例
我正在阅读有关Java中的volatile关键字的信息,并完全理解了它的理论部分。 但是,我要寻找的是一个很好的案例,它显示了如果变量不是volatile的话会发生什么。 以下代码段未按预期运行(从此处获取): class Test extends Thread { boolean keepRunning = true; public void run() { while (keepRunning) { } System.out.println("Thread terminated."); } public static void main(String[] args) throws InterruptedException { Test t = new Test(); t.start(); Thread.sleep(1000); t.keepRunning = false; System.out.println("keepRunning set to false."); } } 理想情况下,如果keepRunning不是volatile,则线程应无限期继续运行。但是,它确实会在几秒钟后停止。 我有两个基本问题: 谁能用例子解释易失性?不符合JLS的理论。 …

2
易变结构语义
将结构类型变量的实例声明为volatile是否足够(如果其字段以可重入代码访问),还是必须将结构的特定字段声明为volatile? 措辞不同,以下两者之间的语义差异(如果有): typdef struct { uint8_t bar; } foo_t; volatile foo_t foo_inst; 和 typedef struct{ volatile uint8_t bar; } foo_t; foo_t foo_inst; 我认识到,将指针类型的变量声明为volatile(例如volatile uint8_t * foo)仅通知编译器foo指向的地址可能会更改,而没有声明foo指向的值。对我来说还不清楚结构类型变量是否适用类推。
74 c  struct  volatile 

3
为什么在std :: atomic中使用了volatile限定符?
从我从Herb Sutter和其他人那里读到的内容来看volatile,至少在C / C ++方面,您会认为并发编程是完全正交的概念。 但是,在GCC实现中,所有std::atomic的成员函数都具有volatile限定符。在Anthony Williams的实现中也是如此std::atomic。 那怎么办,我的atomic<>变量是否需要volatile?
72 c++  c++11  atomic  volatile 

4
为什么Java 5+中的volatile不能确保另一个线程的可见性?
根据: http://www.ibm.com/developerworks/library/j-jtp03304/ 在新的内存模型下,当线程A写入易失性变量V,而线程B从V读取时,现在保证了在写入V时A可见的任何变量值对B可见。 互联网上的许多地方都指出,以下代码永远不应显示“错误”: public class Test { volatile static private int a; static private int b; public static void main(String [] args) throws Exception { for (int i = 0; i < 100; i++) { new Thread() { @Override public void run() { int tt = b; // makes …

3
允许编译器对局部volatile进行常量折叠吗?
考虑以下简单代码: void g(); void foo() { volatile bool x = false; if (x) g(); } https://godbolt.org/z/I2kBY7 您可以看到,也gcc没有clang优化对的潜在调用g。在我的理解中,这是正确的:抽象机器假定volatile变量随时可能更改(由于例如被硬件映射),因此将false初始化不断折叠到if检查中将是错误的。 但是MSVC g完全消除了对的调用(保留对文件的读写volatile!)。这是符合标准的行为吗? 背景:我有时会使用这种结构来即时打开/关闭调试输出:编译器必须始终从内存中读取值,因此在调试过程中更改变量/内存应相应地修改控制流。 。MSVC输出确实重新读取了该值,但忽略了该值(可能是由于不断折叠和/或消除了死代码),这当然违背了我的意图。 编辑: volatile此处讨论了对读写的消除:是否允许编译器优化局部volatile变量?(感谢内森!)。我认为该标准非常明确,即必须进行那些读写操作。但是,该讨论并未涵盖编译器将这些读取结果视为理所当然并基于此进行优化是否合法。我想这是标准中未指定的/未指定的,但是如果有人证明我做错了,我会很高兴。 我当然可以制作x一个非局部变量来避免该问题。这个问题更多是出于好奇。


3
“ volatile”对于多核系统的可移植C代码是否有任何保证?
看着经过一大堆 的 其他 问题 和 他们的 答案,我得到的印象是有什么在C“挥发性”关键字表示正好没有广泛的协议。 即使标准本身似乎也不够清晰,每个人都无法理解其含义。 除其他问题外: 根据您的硬件和编译器,它似乎提供了不同的保证。 它影响编译器优化,但不影响硬件优化,因此在执行自己的运行时优化的高级处理器上,甚至不清楚编译器是否可以阻止您要阻止的任何优化。(某些编译器确实会生成指令来阻止某些系统上的某些硬件优化,但这似乎并未以任何方式进行标准化。) 总结一下问题,似乎(经过大量阅读)“ volatile”保证了类似的结果:该值将不但从/向寄存器,而且至少向内核的L1缓存中读/写,其顺序与读/写出现在代码中。但这似乎没有用,因为在同一个线程中读/写寄存器已经足够,而与L1缓存协调并不能保证与其他线程的协调。我无法想象仅与L1缓存进行同步的重要性。 用途1 唯一广泛同意使用volatile的似乎是旧的或嵌入式系统,其中某些内存位置通过硬件映射到I / O功能,例如内存中的某个位(直接在硬件中)控制灯光。 ,或告诉您键盘按键是否按下的内存中的某个位(因为它是通过硬件直接连接到按键的)。 看来,“用1”不移植的代码,其目标包括多核系统发生。 USE 2 与“ use 1”没什么不同,它是可由中断处理程序(可以控制灯光或从键存储信息)随时读取或写入的内存。但是为此已经存在一个问题,即取决于系统,中断处理程序可能会在 具有自己的内存缓存的不同内核上运行,并且“ volatile”不能保证所有系统上的缓存一致性。 因此,“使用2”似乎超出了“易失性”所能提供的范围。 用途3 我看到的唯一其他无可争议的用途是防止通过不同变量指向指向编译器未意识到的相同内存的不同内存的访问优化。但这可能只是无可争议的,因为人们没有在谈论它-我只看到其中一个提及。而且我认为C标准已经认识到“不同”的指针(例如指向函数的不同args)可能指向同一项目或附近的项目,并且已经指定编译器必须生成即使在这种情况下也可以工作的代码。但是,我无法在最新的标准(500页!)中快速找到此主题。 那么“使用3”也许根本不存在? 因此,我的问题是: 在多核系统的可移植C代码中,“ volatile”是否完全可以保证? 编辑-更新 浏览最新标准后,答案似乎至少是非常有限的: 1.标准针对特定类型“ volatile sig_atomic_t”反复指定特殊处理。但是该标准还说,在多线程程序中使用信号功能会导致不确定的行为。因此,该用例似乎仅限于单线程程序与其信号处理程序之间的通信。 2.该标准还为setjmp / longjmp指定了“ volatile”的明确含义。(在其他问题和答案中给出了重要示例代码)。 因此,更精确的问题变成了: 除了(1)允许单线程程序从其信号处理程序接收信息之外,还是(2)允许setjmp,“ volatile”是否可以保证多核系统的可移植C代码中的任何内容?代码以查看在setjmp和longjmp之间修改的变量? 这仍然是一个是/否问题。 如果为“是”,那么最好显示一个无错误的可移植代码示例,如果省略了“ volatile”,则该示例会出现错误。如果为“ no”,那么我认为对于多核目标,在这两种非常特殊的情况下,编译器可以随意忽略“ volatile”。

1
这个C ++ AtomicInt实现正确吗?
前提:我正在使用甚至没有C ++ 11(带有std::atomic<int>)的ARM嵌入式(几乎是裸机)环境,因此请避免回答“ 仅使用标准C ++”std::atomic<int> ”:我不能。 这个AtomicInt的ARM 实现正确吗?(假设ARM体系结构是ARMv7-A) 您看到一些同步问题吗?是否volatile需要/有用? // File: atomic_int.h #ifndef ATOMIC_INT_H_ #define ATOMIC_INT_H_ #include <stdint.h> class AtomicInt { public: AtomicInt(int32_t init = 0) : atom(init) { } ~AtomicInt() {} int32_t add(int32_t value); // Implement 'add' method in platform-specific file int32_t sub(int32_t value) { return add(-value); } int32_t …
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.