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

C++中的volatile关键字

作用:

1.它用于修饰变量,告知编译器该变量的值可能会在程序的外部被改变,编译器不能对这个变量的访问进行优化。这是因为编译器通常会对代码进行优化,例如把变量的值缓存到寄存器中,但对于 volatile 变量,每次访问都要从内存中读取,以确保获取到最新的值。同时, volatile 还能防止编译器对涉及该变量的操作进行指令重排序。

#include <iostream>
#include <thread>
#include <chrono>
// 共享的volatile变量
volatile bool flag = false;
void waitForFlag() {
while (!flag) {
// 这里每次都会从内存读取flag的值,因为它是volatile的
}
std::cout << "Flag is set to true." << std::endl;
}
int main() {
std::thread t(waitForFlag);
std::this_thread::sleep_for(std::chrono::seconds(2));
flag = true;
t.join();
return 0;
}

在这个例子中, flag 变量被声明为 volatile 。子线程中的 while 循环会一直检查 flag 的值,直到它变为 true 。因为 flag 是 volatile ,编译器不会对 while 循环中 flag 的读取进行优化,会确保每次都从内存读取最新的值,这在多线程或硬件交互的场景下很重要。

2.volatile 可以用来防止编译器对指令进行重排序。在多线程或者中断处理的程序环境中,这种重排序可能会导致程序逻辑错误。 volatile 能够保证操作的顺序按照代码中的顺序执行,从而保证程序的正确性。

volatile 关键字与 const 关键字的区别:

1.const 关键字: 

const 修饰的变量是常量,在定义后不能被修改。它主要用于告诉编译器这个变量的值是固定的,编译器可以利用这一点进行一些优化,例如将变量的值替换到使用它的地方,而不用每次从内存读取。

2.volatile 关键字:

 volatile 修饰的变量是可变的,不过它强调变量的值可能会被程序外部(如硬件设备、其他线程或中断服务程序)改变。编译器不会对 volatile 变量进行优化,每次访问该变量时都会从内存中读取最新的值,并且不会对涉及该变量的操作进行指令重排序。

#include <iostream>
// const示例
void constExample() {
const int a = 10;
// a = 20;  // 这行代码会出错,因为不能修改const变量的值
std::cout << "The value of const variable a: " << a << std::endl;
}
// volatile示例
#include <thread>
#include <chrono>
volatile bool flag = false;
void volatileExample() {
std::thread t1( {
// 等待flag变为true
while (!flag) {
// 因为flag是volatile,每次循环都会从内存读取其最新值
}
std::cout << "Flag is now true." << std::endl;
});
// 主线程等待一段时间后将flag设为true
std::this_thread::sleep_for(std::chrono::seconds(2));
flag = true;
t1.join();
}
int main() {
constExample();
volatileExample();
return 0;
}

在这个示例中, constExample 函数展示了 const 变量不能被修改的特性。 volatileExample 函数通过一个简单的多线程场景展示了 volatile 变量的作用,线程 t1 会一直检查 volatile 变量 flag 的值,直到它被主线程修改为 true 。每次检查时,都会从内存读取 flag 的最新值。

http://www.lryc.cn/news/493566.html

相关文章:

  • linux桌面qt应用程序UI自动化实现之dogtail
  • Hello World C#
  • SAP开发语言ABAP开发入门
  • 应急响应靶机——easy溯源
  • 【前端】vscode报错: 无法加载文件 D:\nodejs\node_global\yarn.ps1,因为在此系统上禁止运行脚本。
  • Spring Web MVC(详解中)
  • Flutter:encrypt插件 AES加密处理
  • Python bytes类型及用法
  • 阅读《基于蒙特卡洛法的破片打击无人机易损性分析》_笔记
  • 【vim】vim怎么把某一列内容复制到另一列
  • IP划分(笔记)
  • 【ChatGPT大模型开发调用】如何获得 OpenAl API Key?
  • 人证合一开启安全认证新时代、C#人证合一接口集成、人脸识别
  • EBS 中 Oracle Payables (AP) 模块的相关集成
  • Flask项目入门—会话技术Cookie和Session
  • 通达OA down存在信息泄露漏洞
  • Python中的简单爬虫
  • Scala入门基础(20)数据集复习拓展
  • leetcode 二叉树的最大深度
  • elasticsearch集群部署及加密通讯
  • ML 系列:第 32节 — 机器学习中的统计简介
  • CatVton升级版?CatVton-Flux:AI虚拟试衣方案新选择。
  • JavaEE---计算机是如何工作的?
  • 十、Spring Boot集成Spring Security之HTTP请求授权
  • C#基础控制台程序
  • 【网络安全】CSRF
  • 网络原理(一)—— http
  • 【实体配置】.NET开源 ORM 框架 SqlSugar 系列
  • 【Zookeeper】四,Zookeeper节点类型、通知、仲裁、会话
  • 【二分查找】力扣 34. 在排序数组中查找元素的第一个和最后一个位置