C++ std::atomic和std::mutex

news2024/9/23 3:13:35

C++11 引入了两个重要的同步机制用于多线程编程:std::atomicstd::mutex。它们各自适用于不同的并发控制需求,并在实现和使用上有很大的不同。

1. 目的和用途

  • std::atomic:

    • 设计目的:为原子操作提供支持,保证对变量的操作(如加载、存储、增加、减少等)是原子的,无需锁。
    • 用途:适用于需要对单个变量进行并发访问并保持高性能的场景,如计数器、标志位等。
  • std::mutex:

    • 设计目的:提供互斥锁,用于保护共享资源,确保同一时刻只有一个线程可以访问某个资源。
    • 用途:适用于复杂的临界区保护,需要确保某个代码段在任何时刻只能被一个线程执行,如保护复杂数据结构、文件操作等。

2. 性能和开销

  • std::atomic:

    • 性能:通常比std::mutex更快,因为它利用了硬件提供的原子操作指令,操作开销相对较低。
    • 开销:几乎没有上下文切换和内核态开销,所有操作都是在用户态完成的。
    • 无锁特性:避免了锁竞争和线程阻塞,可以减少上下文切换的开销。
  • std::mutex:

    • 性能:相对较慢,因为涉及上下文切换和内核态的开销。
    • 开销:需要等待操作,存在线程阻塞的可能性,当线程数较多时容易产生竞争和死锁风险。
    • 锁竞争:多个线程竞争同一个锁时会导致性能下降。

3. 易用性和代码复杂度

  • std::atomic:

    • 易用性:相对简单,只需对变量进行原子操作。
    • 代码复杂度:适用于简单的变量操作,不适用于复杂的临界区保护。
  • std::mutex:

    • 易用性:相对复杂,需要显式地锁定和解锁。
    • 代码复杂度:适用于复杂的临界区保护,需要更仔细地管理锁的生命周期和作用范围,而且要小心避免死锁。

4.使用示例

++操作并不是一个原子操作,该操作分为三步:

  • load:将共享变量n从内存加载到寄存器中。
  • update:更新寄存器里面的值,执行+1操作。
  • store:将新值从寄存器写回共享变量n的内存地址。

多个线程在同一个进程内工作,共享进程的资源,线程本身只拥有线程id、寄存器、线程栈。

因此可能当线程1刚将n的值加载到寄存器中就被切走了,也就是只完成了++操作的第一步,而线程2可能顺利完成了一次完整的++操作才被切走,而这时线程1继续用之前加载到寄存器中的值完成剩余的两步操作,最终就会导致两个线程分别对共享变量n进行了一次++操作,但最终n的值却只被++了一次。

因此需要加锁或者原子类:

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

std::atomic<int> atomic_count(0);
std::mutex mtx;
int count = 0;

void atomic_increment() {
    for (int i = 0; i < 1000; ++i) {
        atomic_count++;
    }
}

void mutex_increment() {
    for (int i = 0; i < 1000; ++i) {
        std::lock_guard<std::mutex> lock(mtx);
        count++;
    }
}

int main() {
    std::thread t1(atomic_increment);
    std::thread t2(atomic_increment);
    t1.join();
    t2.join();
    std::cout << "Atomic count: " << atomic_count << std::endl;

    std::thread t3(mutex_increment);
    std::thread t4(mutex_increment);
    t3.join();
    t4.join();
    std::cout << "Mutex count: " << count << std::endl;

    return 0;
}

5.使用场景

  • std::atomic:适用于简单的、需要高性能的原子变量操作。例如计数器、单一标志等。
  • std::mutex:适用于复杂的临界区保护,例如需要保护复杂的数据结构或资源的访问。

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Python试讲

Python试讲 导语Python简介Python及其特点如何使用Python Python与计算计算变量 导语 本次试讲内容如下&#xff1a;Python简介与使用&#xff0c;Python与基本运算 辅助教材为 《趣学Python编程》和《Python编程从入门到实践》 Python简介 Python是目前入门最简单最好学的…

FVM安装及配置

一、下载fvm 包 git&#xff1a;Release fvm 3.1.7 leoafarias/fvm GitHub 解压到本地文件夹&#xff0c;然后添加环境变量 管理员模式打开cmd&#xff0c;查看是否成功 fvm --version 二、安装Dart SDK 下载Dart SDK&#xff1a;Dart for Windows 三、安装GIT 四、指定…

python3.10安装geopandans实战笔记

1.geopandans安装所需软件库版本 python3.10 GDAL-3.4.3-cp310-cp310-win_amd64.whl【手动下载】 Fiona-1.8.21-cp310-cp310-win_amd64.whl【手动下载】 shapely-2.0.2-cp310-cp310-win_amd64.whl【手动下载】 pyproj 手动下载地址&#xff1a;https://download.csdn.net/down…

range和enumerate的区别

range通过索引遍历元素&#xff0c;属于间接访问。 enumerate直接遍历元素&#xff0c;效率稍高&#xff0c;代码简洁。range输出的是元素的索引。 enumerate输出的是元素的索引和元素。 参考&#xff1a;range与enumerate的区别_enumerate和range-CSDN博客

(一)springboot2.7.6集成activit5.23.0之集成引擎

集成引擎很简单。 首先是创建springboot项目然后引入相关依赖就完成了。pom.xml如下&#xff1a; <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation"http://maven.…

鸿蒙应用框架开发【媒体库视频】 UI框架

媒体库视频 介绍 本示例使用Video组件展示了视频组件的基本功能&#xff0c;包括视频组件化&#xff0c;全屏化&#xff0c;窗口化&#xff0c;上下轮播视频等。 效果预览 使用说明&#xff1a; 进入首页点击播放按键&#xff1b;点击视频播放按钮&#xff0c;视频开始播放…

CTFHub技能树web——XSS——DOM反射

根据框里的内容 直接右键查看网页源代码 看到 了其闭合方式 然后去网页测试一下alert&#xff08;1&#xff09;反射 ;</script><script>alert(1)</script> 看到 确实存在 去xssaq.cn 创建一个项目 把src粘过来 在第一个输入框中 再将返回回来的url 复…

NAND行业回归盈利:AI与云存储需求驱动

市场概览 根据Yole Group于2024年6月25日发布的市场报告&#xff0c;经过五个季度的亏损之后&#xff0c;NAND闪存行业在2024年第一季度&#xff08;1Q24&#xff09;实现了盈利回归。这一转变主要得益于企业级固态硬盘&#xff08;SSD&#xff09;领域的强劲需求增长&#xf…

【教程】Python语言的地球科学常见数据——海温数据-NOAA OISST 的处理

NOAA 1/4每日最佳内插海面温度&#xff08;OISST&#xff09;是一个长期的气候数据记录&#xff0c;它将来自 不同平台&#xff08;卫星、船舶、浮标和 Argo 浮标&#xff09;的观测数据纳入一个定期的全球网格。该 数据集经过插值处理&#xff0c;以填补网格上的空白&#x…

创意无限:11个设计圈热议的UI设计灵感网站集锦

无论你是一个经验丰富的UI设计师还是一个新的UI设计师&#xff0c;拥有一些高质量、可靠的UI设计网站灵感库都能加速你的设计过程。借助灵感资源&#xff0c;您可以更快、更有效地启动该项目。与此同时&#xff0c;优秀的UI设计网站也能帮助您探索新的设计解决方案&#xff0c;…

3DsMax展开管道UV,展开圆柱体UV,展开带有拐弯部分的UV

效果 3dsmax展开管道的UV 创建管道 创建样条线 制作弯曲部分 打开样条线先的顶点&#xff0c;选择样条线的顶点&#xff0c;不选中&#xff0c;开头和结尾的顶点&#xff0c;点击圆角 &#xff0c;鼠标移动到顶点上&#xff0c;左键点击顶点然后向上拖拽。 设置样条线可渲染…

隐私安全测试:保护您的数字世界

大家好&#xff0c;我是一名_全栈_测试开发工程师&#xff0c;已经开源一套【自动化测试框架】和【测试管理平台】&#xff0c;欢迎大家关注我&#xff0c;和我一起【分享测试知识&#xff0c;交流测试技术&#xff0c;趣聊行业热点】。 一、引言 在当今数字化的时代&#xff0…

安装Docker以及安装过程中的错误解决

一、纯享版教程&#xff0b;操作截图 环境&#xff1a;centOs 7 FinalShell &#xff01;&#xff01;&#xff01;此教程针对第一次安装docker的友友&#xff0c;如果已经安装过且报错的朋友&#xff0c;请移步报错合集。 1.卸载旧版本&#xff08;无论是否安装过都建议执…

C++11深度剖析

目录 &#x1f680; 前言&#xff1a;C11简介 一&#xff1a; &#x1f525; 统一的列表初始化&#x1f4ab; 2.1 &#xff5b;&#xff5d;初始化 二&#xff1a; &#x1f525; std::initializer_list &#x1f4ab; 2.1 std::initializer_list是什么类型&#x1f4ab; 2.2 s…

【LLM】-14-搭建问答系统

核心流程说明&#xff1a; 对用户的输入进行检验&#xff0c;验证其是否可以通过审核 API 的标准。若输入顺利通过审核&#xff0c;我们将进一步对产品目录进行搜索。若产品搜索成功&#xff0c;我们将继续寻找相关的产品信息。我们使用模型针对用户的问题进行回答。最后&…

C++ : namespace,输入与输出,函数重载,缺省参数

一&#xff0c;命名空间(namespace) 1.1命名空间的作用与定义 我们在学习c的过程中&#xff0c;经常会碰到命名冲突的情况。就拿我们在c语言中的一个string函数来说吧&#xff1a; int strncat 0; int main() {printf("%d", strncat);return 0; } 当我们运行之后&…

内网横向——常见系统传递攻击(1)

文章目录 一、哈希传递1.1 利用Mimikatz进行PTH1.2 利用Impacket进行PTH1.3 使用crackmapexec进行PTH1.4 使用PowerShell1.5 使用MSF进行哈希传递1.6 利用哈希传递登录远程桌面 二、票据传递2.1 MS14-068漏洞2.2 使用kekeo进行票据传递 网络拓扑&#xff1a; 攻击机kali IP&…

windows内存泄漏检查汇总

VLD(Visual Leak Detector) 下载 官方下载地址2.5 另一分支2.7 安装 点击运行安装

重装系统之前,如何保护自己的微信聊天记录?

前言 有个小伙伴想要重装系统&#xff0c;但又怕自己的电脑微信聊天记录全没了。于是就一直拖着不重装系统&#xff0c;直到有一天系统崩溃之后…… 今天咱们要讲讲&#xff1a;重装系统之前&#xff0c;如何保护自己的社交软件聊天记录。这个话题其实不仅仅是微信聊天记录&am…

喜讯|华院计算Uni-law法律大模型成功入选《2024中国数据智能产业AI大模型先锋企业》

7月24日&#xff0c;“2024企业数智化转型升级发展论坛——暨AI大模型趋势论坛”在北京圆满落幕。此次论坛由数据猿主办&#xff0c;IDC协办&#xff0c;新华社中国经济信息社、上海大数据联盟、上海市数商协会及上海超级计算中心作为支持单位。大会以“数智新质力拓未来”为主…