volatile关键字的作用是 告诉编译器,被该关键字修饰的变量,不允许被优化,保持内存的可见性
概念说完了,下面就是通过画图和代码理解这个概念,这里需要稍微用到一点进程信号的内容
目录
一、优化前
一开始我们不对代码进行优化,只是看看最初的结果是怎么样的,因为代码优化以后的结果会和原本的不同,下面是Makefile文件的内容 和 核心代码
执行信号处理函数时,flag变成了1,此时空循环会退出,打印“退出当前进程!”
二、优化后(寄存器优化)
我们修改Makefile文件,告诉编译器我们希望优化一下这段代码
-O0 是不优化
-O1 是对常量和表达式的优化
-O2 是寄存器级别的优化
-O3 是在-O2的基础上继续优化
然后我们来看看测试结果,结果发现发送2号信号,但是没有退出进程
三、-O2优化的本质
1、优化前分析
我们运行这段代码的时候,会在内存中开辟一块空间来存放flag
while循环要用到flag,CPU就会把flag加载到寄存器中,然后检查条件是否为真,然后根据结果执行下一步
收到2号以后,flag被修改为1,此时退出while循环
2、优化后分析
这个时候,我们使用了 -O2 优化,也就是对寄存器进行了优化,这个时候编译器觉得,这个flag只是在做 检测工作,没有任何修改,于是一开始就把flag读取到CPU的寄存器上,然后就不再从内存读取,每次只用寄存器存储的值来检测while循环的条件
接收到2号信号的时候,修改的是内存上的内容,此时内存上的flag为1,但是因为优化的缘故CPU已经不会从内存读取数据了(因为寄存器把内存给屏蔽了!),所以进程无法退出,因为CPU中flag的值一直为0
四、volatile关键字(解决问题)
这里就引出了volatile关键字,它会告诉编译器,我修饰的变量不要优化!加了volatile以后,CPU就会老老实实去读内存
这个时候我们再运行一下代码