C++11新特性之线程volatile

C++ volatile

在C++中,volatile 是一个类型限定符,用于告诉编译器某个变量的值可能在程序之外被改变。因此,编译器在对该变量进行优化时,必须小心避免去掉或修改对该变量的读取或写入操作。

定义与作用

定义:

volatile关键字用于声明一个变量可能被外部事件(如硬件中断、另一个线程等)修改。
通常用于嵌入式编程和多线程编程中。

功能与作用:

防止编译器对该变量进行优化。
确保每次访问时,编译器都从内存中读取变量的最新值,而不是使用寄存器中缓存的值。

volatile示例代码

以下是一个完整的代码示例,展示了volatile的使用:

#include <iostream>
#include <thread>
#include <atomic>

// 示例1: 使用volatile与普通变量对比
volatile bool stop_flag = false;  // 声明为volatile变量

void workerThread() {
    int counter = 0;
    while (!stop_flag) {  // volatile确保每次从内存读取stop_flag
        counter++;
    }
    std::cout << "Worker thread stopped after " << counter << " iterations." << std::endl;
}

// 示例2: 使用std::atomic代替volatile (推荐用法)
std::atomic<bool> atomic_flag(false);

void atomicWorkerThread() {
    int counter = 0;
    while (!atomic_flag.load()) {  // 原子操作确保线程安全
        counter++;
    }
    std::cout << "Atomic worker thread stopped after " << counter << " iterations." << std::endl;
}

int main() {
    // 使用volatile的线程示例
    std::thread t1(workerThread);
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 主线程暂停1秒
    stop_flag = true;  // 修改volatile变量,通知线程停止
    t1.join();

    // 使用std::atomic的线程示例
    std::thread t2(atomicWorkerThread);
    std::this_thread::sleep_for(std::chrono::seconds(1));  // 主线程暂停1秒
    atomic_flag.store(true);  // 修改atomic变量,通知线程停止
    t2.join();

    return 0;
}

volatile输出结果

Worker thread stopped after 645202174 iterations.
Atomic worker thread stopped after 218850736 iterations.
Worker thread stopped after 713982677 iterations.
Atomic worker thread stopped after 211369915 iterations.

备注:两次输出结果不一样。

代码说明

volatile的作用:

  1. 在workerThread中,stop_flag被声明为volatile,这保证了线程会读取stop_flag的最新值,而不会被编译器优化成读取缓存值。
  2. 如果没有volatile修饰,编译器可能会优化掉循环中的stop_flag读取,导致线程无法正确停止。

推荐用法:

在多线程编程中,std::atomic更推荐使用,因为它不仅防止优化,还提供线程安全性,避免数据竞争。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/938587.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Windows server服务器之网络安全管理(防火墙入站规则创建)

任务14.1 Windows server 防火墙的管理 系统防火墙概述&#xff1a;无论哪一种操作系统都有自己的防火墙&#xff0c;无论是客户端OS还是服务器端的NOS都有防火墙。 winr-control----打开控制面板 上图是Windows客户端的防火墙&#xff0c;三个重点要关注的内容&#xff1b;网…

【Python】PyWebIO 初体验:用 Python 写网页

目录 前言1 使用方法1.1 安装 Pywebio1.2 输出内容1.3 输入内容 2 示例程序2.1 BMI 计算器2.2 Markdown 编辑器2.3 聊天室2.4 五子棋 前言 前两天正在逛 Github&#xff0c;偶然看到一个很有意思的项目&#xff1a;PyWebIo。 这是一个 Python 第三方库&#xff0c;可以只用 P…

四、CSS3

一、CSS3简介 1、CSS3概述 CSS3 是 CSS2 的升级版本&#xff0c;他在CSS2的基础上&#xff0c;新增了很多强大的新功能&#xff0c;从而解决一些实际面临的问题。 CSS在未来会按照模块化的方式去发展&#xff1a;https://www.w3.org/Style/CSS/current-work.html …

Loki 微服务模式组件介绍

目录 一、简介 二、架构图 三、组件介绍 Distributor&#xff08;分发器&#xff09; Ingester&#xff08;存储器&#xff09; Querier&#xff08;查询器&#xff09; Query Frontend&#xff08;查询前端&#xff09; Index Gateway&#xff08;索引网关&#xff09…

上海亚商投顾:创业板指缩量下跌 多只高位股午后跌停

上海亚商投顾前言&#xff1a;无惧大盘涨跌&#xff0c;解密龙虎榜资金&#xff0c;跟踪一线游资和机构资金动向&#xff0c;识别短期热点和强势个股。 一.市场情绪 市场全天震荡调整&#xff0c;创业板指领跌&#xff0c;高位股开始出现退潮&#xff0c;建设工业、星光股份、…

libnanomsg详解

libnanomsg&#xff0c;或简称为nanomsg&#xff0c;是一个高性能的消息传递库&#xff0c;它为开发者提供了简单且高效的“可扩展协议”实现。以下是对libnanomsg的详细解析&#xff1a; 一、基本概述 项目地址&#xff1a;GitCode - 全球开发者的开源社区,开源代码托管平台 …

MySQL基础大全(看这一篇足够!!!)

文章目录 前言一、初识MySQL1.1 数据库基础1.2 数据库技术构成1.2.1 数据库系统1.2.2 SQL语言1.2.3 数据库访问接口 1.3 什么是MySQL 二、数据库的基本操作2.1 数据库创建和删除2.2 数据库存储引擎2.2.1 MySQL存储引擎简介2.2.2 InnoDB存储引擎2.2.3 MyISAM存储引擎2.2.4 存储引…

geoserver 瓦片地图,tomcat和nginx实现负载均衡

在地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;GeoServer作为一个强大的开源服务器&#xff0c;能够发布各种地图服务&#xff0c;包括瓦片地图服务。为了提高服务的可用性和扩展性&#xff0c;结合Tomcat和Nginx实现负载均衡成为了一个有效的解决方案。本文将详细…

Spark执行计划解析后是如何触发执行的?

在前一篇Spark SQL 执行计划解析源码分析中&#xff0c;笔者分析了Spark SQL 执行计划的解析&#xff0c;很多文章甚至Spark相关的书籍在讲完执行计划解析之后就开始进入讲解Stage切分和调度Task执行&#xff0c;每个概念之间没有强烈的关联&#xff0c;因此这中间总感觉少了点…

前端的知识(部分)

11 前端的编写步骤 第一步:在HTML的页面中声明方法 第二步:在<script>中定义一个函数,其中声明一个data来为需要的数据 赋值一个初始值 第三步:编写这个方法实现对应的功能

网络编程中的黏包和半包问题

引言 - 什么是黏包和半包&#xff1f; 在网络编程中&#xff0c;黏包和半包问题是常见的数据传输问题&#xff0c;尤其是在使用TCP协议时。Netty作为一个高性能的网络框架&#xff0c;提供了多种解决方案来处理这些问题。下面我将详细解释黏包和半包问题&#xff0c;以及Netty…

F5中获取客户端ip地址(client ip)

当F5设备对其原始设置上的所有IP地址使用NAT时&#xff0c;连接到poo成员&#xff08;nodes、backend servers&#xff09;的出站连接将是NAT IP地址。 pool 成员&#xff08;nodes、backend servers&#xff09;将无法看到真实的客户端 ip地址&#xff0c;因为看到的是F5上的…

【容器】k8s学习笔记原理详解(十万字超详细)

Pod详解 Pod介绍 Pod结构 每个Pod中都可以包含一个或者多个容器&#xff0c;这些容器可以分为两类&#xff1a; 用户程序所在的容器&#xff0c;数量可多可少Pause容器&#xff0c;这是每个Pod都会有的一个根容器&#xff0c;它的作用有两个&#xff1a; 可以以它为依据&am…

【他山之石】Leading-Trim: The Future of Digital Typesetting:数字排版的未来 —— Leading-Trim

文章目录 【他山之石】Leading-Trim: The Future of Digital Typesetting&#xff1a;数字排版的未来 —— Leading-TrimHow an emerging CSS standard can fix old problems and raise the bar for web apps1. The problem with text boxes today2. How we got here: a histor…

vue3修改elementui-plus的默认样式的几种方法

#创作灵感 今天写vue的前端项目&#xff0c;因为需要去修改elementui-plus中drawer的默认样式&#xff0c;所以刚好将修改步骤记录下来。 一共提供了三种方法&#xff0c;但亲测第二种最好用。 使用第二种是可以无视自己的代码中是否定义了该盒子&#xff0c;因为有时候盒子的…

Qt WORD/PDF(四)使用 QAxObject 对 Word 替换(QWidget)

关于QT Widget 其它文章请点击这里: QT Widget 国际站点 GitHub: https://github.com/chenchuhan 国内站点 Gitee : https://gitee.com/chuck_chee 姊妹篇: Qt WORD/PDF&#xff08;一&#xff09;使用 QtPdfium库实现 PDF 操作 Qt WORD/PDF&#xff08;二…

MaskGCT——开源文本转语音模型,可模仿任何人说话声音

前期介绍过很多语音合成的模型&#xff0c;比如ChatTTS&#xff0c;微软语音合成大模型&#xff0c;字节跳动自家发布的语音合成模型Seed-TTS。其模型随着技术的不断发展&#xff0c;模型说话的声音也越来越像人类&#xff0c;虽然 seed-tts 可以进行语音合成等功能&#xff0c…

socket编程UDP-实现滑动窗口机制与累积确认GBN

在下面博客中&#xff0c;我介绍了利用UDP模拟TCP连接、按数据包发送文件的过程&#xff0c;并附上完整源码。 socket编程UDP-文件传输&模拟TCP建立连接脱离连接&#xff08;进阶篇&#xff09;_udp socket发送-CSDN博客 下面博客实现了停等机制。 socket编程UDP-实现停…

Linux 网络流量控制 - 实现概述

摘要 Linux 提供了一整套丰富的流量控制(traffic control)功能。本文档概述了相应的内核代码设计&#xff0c;描述了其结构&#xff0c;并通过描述一种新的排队策略来说明新元素的添加。 1 引言 最近的Linux内核提供了多种流量控制功能。Alexey Kuznetsov&#xff08;kuznet…

学习日志024--opencv中处理轮廓的函数

目录 前言​​​​​​​ 一、 梯度处理的sobel算子函数 功能 参数 返回值 代码演示 二、梯度处理拉普拉斯算子 功能 参数 返回值 代码演示 三、Canny算子 功能 参数 返回值 代码演示 四、findContours函数与drawContours函数 功能 参数 返回值 代码演示 …