«

C++中的volatile关键字怎么使用

时间:2024-6-10 11:15     作者:韩俊     分类: Java


本文小编为大家详细介绍“C++中的volatile关键字怎么使用”,内容详细,步骤清晰,细节处理妥当,希望这篇“C++中的volatile关键字怎么使用”文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

volatile是C语言的一个关键字,该关键字的作用是保持内存的可见性

例子:

我们对2号信号进行了捕捉,当该进程收到2号信号时会将全局变量flag由0置1, 也就是说,在进程收到2号信号之前,该进程会一直处于死循环状态,直到收到2号信号时将flag置1才能够正常退出

#include <stdio.h>
#include <signal.h>
int flag = 0;
void handle(int signo)
{
    printf("收到一个 %d号信号
",signo);
    flag = 1;
}
int main()
{
    signal(2,handle);//捕获2号信号
    while(!flag);
    printf("进程正常退出!
");
    return 0;
}

上述代码中:main函数和handler函数是两个独立的执行流

判断一个数据为真为假 -> 逻辑运算 -> 需要CPU参与 ,常规情况下,需要从内存加载到CPU,然后CPU内部做判断,然后再把结果返回

而while循环是在main函数当中的,编译器发现:我们只对flag这个变量做检测,而不做修改, 编译器直接优化,把flag的值保存在寄存器中,直接在CPU检测

此时main函数在检测flag时只检测寄存器里面的值,而handler执行流只是将内存中flag的值置为1了,那么此时就算进程收到2号信号也不会跳出死循环

检验:在编译器优化级别较高的时候,就有可能将flag设置进寄存器里面

如何提高编译时的优先级呢? 在编译代码时携带 -O3 选项使得编译器的优化级别最高 

此时再运行该代码,就算向进程发生2号信号,该进程也不会终止

此时我们可以使用volatile关键字对flag变量进行修饰,告知编译器,对flag变量的任何操作都必须真实的在内存中进行,即保持了内存的可见性

#include <stdio.h>
#include <signal.h>
volatile int flag = 0;//告知编译器,对flag变量的任何操作都必须真实的在内存中进行
void handle(int signo)
{
    printf("收到一个 %d号信号
",signo);
    flag = 1;
}
int main()
{
    signal(2,handle);//捕获2号信号
    while(!flag);
    printf("进程正常退出!
");
    return 0;
}

此时就算我们编译代码时携带 -O3 选项,当进程收到2号信号将内存中的flag变量置1时,main函数执行流也能够检测到内存中flag变量的变化,进而跳出死循环正常退出

标签: java

热门推荐