当前位置: 首页 > news >正文

Linux | C语言中volatile关键字的理解

目录

前言

一、代码引入

二、现象解释

三、具体引用


前言

        本章主要讲解介绍volatile关键的作用与使用场合;深刻理解volatile关键字;本文你需要有信号相关的基础知识;

Linux | 信号-CSDN博客

一、代码引入

        首先,我们来查看下面这段代码;

#include <iostream>
#include <signal.h>// 定义全局变量
int flag = 1;void handler(int signum)
{(void)(signum); // 防止编译器警告std::cout << "change before flag:" << flag << std::endl;flag = 0;std::cout << "change after flag:" << flag << std::endl;
}int main()
{// 对2号信号捕捉signal(SIGINT, handler);// 死循环while(flag);std::cout << "run here..." << std::endl;return 0;
}

        当我们发送2号信号时,全局变量flag被改为了0,然后循环条件不满足,打印 run here 后退出;我们运行查看结果是否满足我们预期结果;如下所示;

        第一个红色框起来的是我们编译程序所用指令;第二个红色框起来的是当我们按下 ctrl + c 发送2号信号时,程序如我么预期所料;

        接下来,我们来介绍以下 gcc/g++ 的几个编译选项;如下图所示;

        -O1、-O2、-O3分别为编译时三个不同等级的优化,其中优化程度由低到高,我们选择最高等级,再次编译运行代码;如下所示;

        神奇的一幕发生了,我们发现我们无论按多少次 ctrl + c 都无法退出程序,我们发送2号信号,也被处理了,我们的全局变量flag不是被置为0了吗?为什么还是没有办法退出while循环呢?下面我们来仔细讲解这个神奇现象;

二、现象解释

        实际上,这就是跟我们的编译器优化有关,我们把视角拉到代码中;如下图所示;

        我们的while循环判断分为以上三个步骤,而当我们编译时对代码采用 O3 级别的优化时,我们的编译器检测到循环中没有对全局变量flag进行修改,因此直接将上面的步骤优化成了如下所示;

        故即使我们发送2号信号将内存中的flag更改,但是判断时时候,依旧直接判断寄存器中flag的那个值;所以才会看到上述那种神奇现象;

三、具体引用

        我们本文的主角volatile关键字就是为了防止这种编译器过度优化的现象,我们可以在定义flag变量的前面加上一个 volatile关键字,这样可以防止我们的变量flag参与被编译器编译的代码过度优化;

#include <iostream>
#include <signal.h>// 定义全局变量(增加volatile关键字)
volatile int flag = 1;void handler(int signum)
{(void)(signum); // 防止编译器警告std::cout << "change before flag:" << flag << std::endl;flag = 0;std::cout << "change after flag:" << flag << std::endl;
}int main()
{// 对2号信号捕捉signal(SIGINT, handler);// 死循环while(flag);std::cout << "run here..." << std::endl;return 0;
}

        代码几乎完全相同,就加入了一个volatile关键字,避免了这种编译器过度优化现象;

相关文章:

Linux | C语言中volatile关键字的理解

目录 前言 一、代码引入 二、现象解释 三、具体引用 前言 本章主要讲解介绍volatile关键的作用与使用场合&#xff1b;深刻理解volatile关键字&#xff1b;本文你需要有信号相关的基础知识&#xff1b; Linux | 信号-CSDN博客 一、代码引入 首先&#xff0c;我们来查看下面…...

汇编层面有三个主要的操作对象

1.为啥会有addi指令&#xff1f; 在汇编层面有三个主要的操作对象&#xff1a;寄存器&#xff0c;内存&#xff0c;立即数&#xff0c;它们是完全不同&#xff0c;不可以混淆&#xff0c;组织结构也不一样的不同对象&#xff0c;所以不能单纯拿针对寄存器的指令去处理内存和立…...

React中的Redux:简介和实例代码

React是一个流行的JavaScript库&#xff0c;用于构建用户界面。它提供了一种简单而强大的方式来构建交互式的界面。Redux是一个用于管理应用程序状态的JavaScript库。它可以与React一起使用&#xff0c;以帮助管理React应用程序的状态。 引言 在本文中&#xff0c;我们将介绍R…...

Modbus转Profinet网关在金银精炼控制系统中应用案例

金银精炼控制系统中采用Modbus转Profinet网关&#xff08;XD-MDPN100&#xff09;连接1200plc与PID控制阀门进行通讯&#xff0c;通过控制PID阀门的大小来实现温度的恒温控制。这一系统的好处在于它能够提高金银精炼过程的效率和精确度。PID控制阀门可以根据温度的变化实时调整…...

小程序商城免费搭建之java商城 电子商务Spring Cloud+Spring Boot+二次开发+mybatis+MQ+VR全景+b2b2c

1. 涉及平台 平台管理、商家端&#xff08;PC端、手机端&#xff09;、买家平台&#xff08;H5/公众号、小程序、APP端&#xff08;IOS/Android&#xff09;、微服务平台&#xff08;业务服务&#xff09; 2. 核心架构 Spring Cloud、Spring Boot、Mybatis、Redis 3. 前端框架…...

Rabin加解密算法(python3)

Rabin加解密算法 详细代码如下&#xff1a; # 空空 # dahouzi.cn import random from sympy import isprimedef decrypt_rabin(c, p, q):"""解密 Rabin 密文Args:c (int): 密文p (int): 素数 pq (int): 素数 qReturns:tuple: 解密结果 M1, M2, M3, M4"&q…...

【带头学C++】----- 七、链表 ---- 7.5 学生管理系统(链表--上)

目录 1.main函数设计 2.定义Node节点类型 3.链表插入结点 在main函数中调用插入函数、打印函数 插入结点函数实现&#xff08;头插法&#xff09; 插入结点函数实现&#xff08;尾插法&#xff09; 遍历链表函数实现 4.演示插入、遍历结果 目录 1.main函数设计 2.定义…...

(四)什么是Vite——冷启动时vite做了什么(源码、middlewares)

vite分享ppt&#xff0c;感兴趣的可以下载&#xff1a; ​​​​​​​Vite分享、原理介绍ppt 什么是vite系列目录&#xff1a; &#xff08;一&#xff09;什么是Vite——vite介绍与使用-CSDN博客 &#xff08;二&#xff09;什么是Vite——Vite 和 Webpack 区别&#xff0…...

Docker部署MinIO对象存储服务器结合Cpolar实现远程访问

&#x1f525;博客主页&#xff1a; 小羊失眠啦. &#x1f3a5;系列专栏&#xff1a;《C语言》 《数据结构》 《Linux》《Cpolar》 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 文章目录 前言1. Docker 部署MinIO2. 本地访问MinIO3. Linux安装Cpolar4. 配置MinIO公网地址5. 远…...

C#入门(1):程序结构、数据类型

一、C#程序结构 第一个C#程序 using System;namespace base_01 {class Program{#region 代码折叠块static void Main(string[] args){//控制台输出Console.WriteLine("Hello World!");Console.Write("C#是微软的编程语言"); //不换行输出//Console.Rea…...

Scala---元组

1、元组定义 与列表一样&#xff0c;与列表不同的是元组可以包含不同类型的元素。元组的值是通过将单个的值包含在圆括号中构成的。 2、创建元组与取值 val tuple new Tuple&#xff08;1&#xff09; 可以使用newval tuple2 Tuple&#xff08;1,2&#xff09; 可以不使…...

【Linux】冯诺依曼体系结构、操作系统、进程概念、进程状态、环境变量、进程地址空间

目录 一、冯诺依曼体系结构二、操作系统(OS)1. 操作系统是什么2. 操作系统如何做管理3. 系统调用和库函数概念 三、进程1. 进程是什么&#xff1f;2. 描述进程-PCB3. 查看进程的方法 四、进程状态1 运行、阻塞和挂起状态2 Linux中的进程状态 五、进程优先级1. 什么是优先级2.查…...

【hive-解决】HiveAccessControlException Permission denied: CREATEFUNCTION

文章目录 一.任务描述二. 解决 一.任务描述 Error while compiling statement: FAILED: HiveAccessControlException Permission denied: Principal [nameroot, typeUSER] does not have following privileges for operation CREATEFUNCTION [ADMIN PRIVILEGE on INPUT, ADMIN…...

内网穿透的应用-通过内网穿透快速搭建公网可访问的Spring Boot接口调试环境

文章目录 前言1. 本地环境搭建1.1 环境参数1.2 搭建springboot服务项目 2. 内网穿透2.1 安装配置cpolar内网穿透2.1.1 windows系统2.1.2 linux系统 2.2 创建隧道映射本地端口2.3 测试公网地址 3. 固定公网地址3.1 保留一个二级子域名3.2 配置二级子域名3.2 测试使用固定公网地址…...

解决 uniapp 开发微信小程序 不能使用本地图片作为背景图 问题

参考博文&#xff1a;uniapp微信小程序无法使用本地静态资源图片(背景图在真机不显示)的解决方法_javascript技巧_脚本之家 问题&#xff1a;uniapp 开发微信小程序&#xff0c;当使用本地图片作为 background-image 时&#xff0c;真机无法显示 解决&#xff1a; 方法一&am…...

常用中间件封装思路粗记

MQ 自定义注解 &#xff0c;编写配置类在bean属性初始化SmartInitializingSingleton#afterSingletonsInstantiated后至处理器 去扫描有自定义注解的bean&#xff0c;去创建对应消费者的容器 并启动消费者容器类主要组件DefaultMQPushConsumer SmartInitializingSingleton#afte…...

探索SPI:深入理解原理、源码与应用场景

文章目录 一、初步认识1、概念2、工作原理3、作用场景 二、源码分析1、ServiceLoader结构2、相关字段3、核心方法 三、案例connector连接器小案例1、新建SPI项目2、创建扩展实现项目1-MongoDB3、创建扩展实现项目2-Oracle4、测试 Spring应用1、创建study工程2、创建forlan-test…...

Web3名词解释

Web3名词解释 以太坊 ERC20 Defi去中心化金融 Defi是Decentralized Finance的英文缩写。 简单理解点就是与传统的高度中心化金融体系相比&#xff0c;去中心化金融是通过区块链技术&#xff0c;比如基于区块链技术开发的手机钱包软件&#xff0c;通过智能合约代码以实现去除…...

Vatee万腾外汇市场新力量:vatee科技决策力

在当今数字化时代&#xff0c;Vatee万腾崭露头角&#xff0c;以其强大的科技决策力进军外汇市场&#xff0c;成为该领域的新力量。这一新动向将不仅塑造外汇市场的未来&#xff0c;也展现Vatee科技决策力在金融领域的引领作用。 Vatee万腾带着先进的科技决策力进入外汇市场&…...

【HarmonyOS开发】配置开发工具DevEco Studio

1、下载 注意&#xff1a; 1、安装过程中&#xff0c;一定要自定义安装位置&#xff0c;包比较大&#xff0c;包比较大&#xff0c;包比较大&#xff01;&#xff01;&#xff01; 2、可以将该工具添加到右键中&#xff0c;否则&#xff0c;如果你的项目不是HarmonyOS&#xff…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

stm32G473的flash模式是单bank还是双bank?

今天突然有人stm32G473的flash模式是单bank还是双bank&#xff1f;由于时间太久&#xff0c;我真忘记了。搜搜发现&#xff0c;还真有人和我一样。见下面的链接&#xff1a;https://shequ.stmicroelectronics.cn/forum.php?modviewthread&tid644563 根据STM32G4系列参考手…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

《用户共鸣指数(E)驱动品牌大模型种草:如何抢占大模型搜索结果情感高地》

在注意力分散、内容高度同质化的时代&#xff0c;情感连接已成为品牌破圈的关键通道。我们在服务大量品牌客户的过程中发现&#xff0c;消费者对内容的“有感”程度&#xff0c;正日益成为影响品牌传播效率与转化率的核心变量。在生成式AI驱动的内容生成与推荐环境中&#xff0…...

Robots.txt 文件

什么是robots.txt&#xff1f; robots.txt 是一个位于网站根目录下的文本文件&#xff08;如&#xff1a;https://example.com/robots.txt&#xff09;&#xff0c;它用于指导网络爬虫&#xff08;如搜索引擎的蜘蛛程序&#xff09;如何抓取该网站的内容。这个文件遵循 Robots…...

2025盘古石杯决赛【手机取证】

前言 第三届盘古石杯国际电子数据取证大赛决赛 最后一题没有解出来&#xff0c;实在找不到&#xff0c;希望有大佬教一下我。 还有就会议时间&#xff0c;我感觉不是图片时间&#xff0c;因为在电脑看到是其他时间用老会议系统开的会。 手机取证 1、分析鸿蒙手机检材&#x…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

【Veristand】Veristand环境安装教程-Linux RT / Windows

首先声明&#xff0c;此教程是针对Simulink编译模型并导入Veristand中编写的&#xff0c;同时需要注意的是老用户编译可能用的是Veristand Model Framework&#xff0c;那个是历史版本&#xff0c;且NI不会再维护&#xff0c;新版本编译支持为VeriStand Model Generation Suppo…...