关于volatile关键字的问题
volatile关键字在低级编程中主要用于中断等场景。如果不将变量声明为volatile,则编译器可能会注意到在while循环中count不会改变,因此不会从内存中读取值,导致循环永远无法退出。而如果声明为volatile,则编译器会每次都从内存中读取值,因为你告诉它该值可能会在没有通知的情况下改变。
另一个用途是映射硬件端口。在微控制器上,你可能有一些数字输入,它们在某个内存地址上“出现”。你可以像读取变量一样读取它们,但是值会根据输入信号不断变化。将该值声明为volatile会告诉编译器,你确实需要每次都读取这个内存位置,因为它可能已经改变了,你不能假设它不会改变除非你改变它。
除非你使用低级中断或线程的某些用途,否则不需要使用volatile。
编辑:要明确,volatile不是用于标准C++中线程之间的同步,它只完成了必要的部分。我原始帖子中的最后一句可能会引起误导。我帖子中关于硬件中断等的示例是volatile的用途,它绝对不是用于线程的,甚至不要尝试使用它来实现线程同步。
再次说明,不要将volatile用于跨线程同步,这是不可靠的。我会修改这个回答,以确保清楚(假设3年后它允许我修改!)
添加了一个编辑说明volatile与线程无关,并且通常不能用于线程,它的作用是确保数据的读写不会重新排序,并且每次访问内存位置。同时解释了为什么三年前我提到了线程。我当时写了“某些用途”,在某些情况下它可能会“工作”,但不要这样做!
在上述代码中,变量k被声明为volatile int类型。volatile关键字用于标识变量可能会被多个线程同时访问和修改,因此编译器不能对其进行优化,而是每次都从内存中重新获取其值。
在第一个示例中,变量k未被声明为volatile,因此编译器可以对代码进行优化,将多次使用k的地方合并为一次赋值操作。这意味着变量k的值只需要获取一次,并可以在内存中缓存,而不必每次都从内存中重新获取。
然而,在第二个示例中,变量k被声明为volatile,这告诉编译器变量k可能会被其他线程修改,因此编译器不能对代码进行优化。这意味着每次访问变量k时,编译器都会重新从内存中获取其最新值,而不是使用缓存的值。
通过使用volatile关键字,我们可以确保对于被多个线程访问和修改的变量,每次访问都能获取到最新的值,而不会使用过期的缓存值。这对于需要保证数据的一致性和可见性的多线程程序非常重要。
总结起来,volatile关键字的作用是告诉编译器不要对变量进行优化,每次使用变量时都需要从内存中重新获取其最新值。这样可以确保多个线程对变量的访问都能获取到正确的值,保证数据的一致性和可见性。
volatile关键字的出现原因是为了防止编译器进行优化,并告诉编译器声明为volatile的变量的内容可以随时更改(即硬件设备、中断或其他线程启动并写入变量的内存位置)。这意味着无法将值缓存到CPU寄存器中。
以下是一些示例:
volatile int a = foo(); d=a+4; e=a+4; f=a+4;
在这个例子中,每次使用a时,编译器被强制从内存中读取。如果没有volatile,预计算a+4将是一个有效的优化。
volatile int a = 4; return a+5;
在这个例子中,编译器不允许将其优化为简单的return 9;,因为a的内容可能在初始化(第1行)和第一次使用(第2行)之间发生变化。
volatile与线程和中断无关。
整个问题的意思是,volatile关键字用于告诉编译器不能对变量进行优化,因为变量的值可能会在编译器无法预测的情况下发生改变。通过使用volatile关键字,可以确保在使用变量时,每次都从内存中读取最新的值。