第十五问:volatile是什么?有什么用?

简介: 本文深入探讨了C/C++中的`volatile`关键字,解释了其防止编译器不当优化、保证多线程间可见性和确保硬件状态正确读写的作用。同时,文章也指出了使用`volatile`可能带来的性能影响,并强调了它在多线程同步中的局限性。通过具体示例,帮助读者更好地理解和应用这一强大工具。

第十五问:volatile是什么?有什么用?


引言

在C和C++编程的世界里,有一个关键字像魔法一样,悄无声息地影响着程序的运行效率和正确性,它就是volatile。本文将深入探讨volatile关键字的作用、使用场景以及需要注意的事项,帮助你更好地理解和应用这个看似简单却功能强大的工具。

一、volatile的魔力:防止不恰当的优化

作用:

  • 防止编译器优化:编译器为了提高程序的执行效率,常常会对代码进行优化。然而,这些优化在某些情况下可能会导致程序行为的错误。例如,编译器可能会将多次读取同一个变量的操作优化成一次读取并缓存结果。

示例:

volatile int flag = 0;
while (flag == 0) {
   // 做一些事情
}

在这个例子中,flag被声明为volatile,确保每次循环都会从内存中读取flag的最新值,而不是使用可能被缓存的旧值。

二、多线程编程中的volatile

作用:

  • 保证线程间可见性:在多线程环境中,volatile确保一个线程对变量的修改能被其他线程立即看到,避免了由于编译器优化导致的线程间数据不一致。

示例:

volatile bool done = false;

void threadFunction() {
   // 做一些工作
   done = true;
}

int main() {
   std::thread t(threadFunction);
   while (!done) {
       // 等待线程完成工作
   }
   t.join();
   return 0;
}

在这个多线程示例中,done被声明为volatile,确保主线程能够立即看到threadFunction线程对done的修改。

三、与硬件交互的volatile

作用:

  • 确保硬件状态的正确读取和写入:当程序与硬件设备交互时,硬件可能会在任何时候改变某个变量的值。volatile确保程序能够正确地读取和写入这些可能被硬件修改的变量。

示例:

volatile unsigned char *port = (volatile unsigned char *)0x3F8; // 假设这是串口地址

void writeToPort(char data) {
   *port = data; // 确保每次写入都是直接到硬件
}

在这个例子中,port被声明为volatile,确保每次对其的读写操作都是直接与硬件交互,而不是通过缓存。

四、注意事项

  • 性能影响:使用volatile会阻止编译器进行一些优化,可能会影响程序性能。
  • 并非万能volatile不能解决所有多线程同步问题,它只保证可见性,不保证原子性或顺序性。

结论

volatile关键字在C/C++中扮演着一个独特的角色,它不仅是编译器优化的一个限制器,也是多线程编程和硬件交互的关键工具。正确使用volatile可以确保程序的正确性和稳定性,但也需要结合其他同步机制来实现更复杂的并发控制。希望通过本文的介绍,你能更好地理解和应用volatile,让你的代码更加健壮和高效。

目录
相关文章
|
传感器 缓存 安全
volatile 相关整理
volatile 相关整理
75 0
|
4月前
|
缓存 Java
【多线程面试题二十三】、 说说你对读写锁的了解volatile关键字有什么用?
这篇文章讨论了Java中的`volatile`关键字,解释了它如何保证变量的可见性和禁止指令重排,以及它不能保证复合操作的原子性。
|
5月前
|
存储 缓存 Java
(一) 玩命死磕Java内存模型(JMM)与 Volatile关键字底层原理
文章的阐述思路为:先阐述`JVM`内存模型、硬件与`OS`(操作系统)内存区域架构、`Java`多线程原理以及`Java`内存模型`JMM`之间的关联关系后,再对`Java`内存模型进行进一步剖析,毕竟许多小伙伴很容易将`Java`内存模型(`JMM`)和`JVM`内存模型的概念相互混淆,本文的目的就是帮助各位彻底理解`JMM`内存模型。
124 0
|
传感器 缓存 安全
JUC第六讲:二面阿里竟然败在了 volatile 关键字上
JUC第六讲:二面阿里竟然败在了 volatile 关键字上
105 0
|
Java
关于关键字volatile的一二
关于关键字volatile的一二
82 0
|
存储 Java 编译器
重学Volatile
并发,是多个线程去访问同一个资源;并行,各种事情同时在做。 volatile是java虚拟机提供的**轻量级**的**同步机制** 三大特性,保证可见性,不保证原子性,禁止指令重排序 先说下JMM(java内存模型Java Memory Model)本身是一种抽象的概念并不是真实存在的,它描述的是一组规则或规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素)的访问方式。
69 0
|
编译器 C语言
C语言程序设计——volatile关键字、函数重入
C语言程序设计——volatile关键字、函数重入
140 0
C语言程序设计——volatile关键字、函数重入
|
编译器
C零散知识点汇总之volatile关键字
C零散知识点汇总之volatile关键字
|
Java
万字长文带你彻底理解synchronized关键字(下)
1、Synchronized关键字的简介,主要是为什么要使用Synchronized关键字,极其作用地位。 2、Synchronized关键字的使用,主要是从对象锁和类锁两个角度。 3、Synchronized关键字的使用注意事项。分析了6种常见的使用情况。 4、Synchronized关键字的两个性质,主要是可重入性和不可中断性。 5、Synchronized关键字的底层原理。 6、Synchronized关键字的常见缺陷。 以上我们主要是从这7个角度来分析Synchronized关键字,每一个角度说实话都能单独拿出来作为一篇文章来分析。但是由于考虑到文章的连贯性,所以综合在了一
105 0
万字长文带你彻底理解synchronized关键字(下)
|
安全 Java
万字长文带你彻底理解synchronized关键字(上)
Synchronized关键字一直是工作和面试中的重点。这篇文章准备彻彻底底的从基础使用到原理缺陷等各个方面来一个分析,这篇文章由于篇幅比较长,但是如果你有时间和耐心,相信会有一个比较大的收获,所以,学习请慢慢来。这篇文章主要从以下几个方面进行分析讲解. 1、Synchronized关键字的简介,主要是为什么要使用Synchronized关键字,极其作用地位。 2、Synchronized关键字的使用,主要是从对象锁和类锁两个角度。 3、Synchronized关键字的使用注意事项。分析了6种常见的使用情况。 4、Synchronized关键字的两个性质,主要是可重入性和不可中断性。
129 0
万字长文带你彻底理解synchronized关键字(上)