《C++11》并发库:简介与应用
在C++11之前,C++并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API(如Windows的CreateThread或POSIX的pthread_create)或者第三方库(如Boost.Thread)来创建和管理线程。这些方式存在以下几个问题:
-
平台依赖:不同的操作系统提供了不同的线程API,这意味着你需要为每个目标平台编写不同的代码,或者使用预处理器宏来处理平台差异。这会使代码变得复杂和难以维护。
-
错误处理困难:操作系统的线程API通常通过返回错误码来报告错误,这需要你在每次调用API后检查错误码,并手动处理错误。这不仅繁琐,而且容易出错。
-
缺乏高级特性:操作系统的线程API通常只提供了基础的线程创建和同步功能,缺乏一些高级特性,如线程池、future和promise等。
相比之下,C++11的并发库提供了以下优势:
-
平台无关:C++11的并发库是C++标准的一部分,这意味着你可以在任何支持C++11的编译器上使用它,无需考虑平台差异。
-
异常安全:C++11的并发库使用异常来报告错误,这使得错误处理更加简单和安全。例如,如果你试图在已经启动的线程上调用
std::thread::join
,C++11会抛出一个std::system_error
异常。 -
高级特性:C++11的并发库提供了一些高级特性,如
std::async
、std::future
和std::promise
等,这些特性使得并发编程更加方便和强大。
这些工具使得C++程序员可以更方便、更安全地编写多线程代码。下面我们将详细介绍这些并发工具的使用。
1. 线程(std::thread)
C++11的std::thread
类提供了对操作系统原生线程的封装。你可以通过创建std::thread
对象来创建新的线程,并通过成员函数join()
或detach()
来等待线程结束或让线程在后台运行。
#include <iostream>
#include <thread>void hello() {std::cout << "Hello, concurrent world\n";
}int main() {std::thread t(hello);t.join();
}
在这个例子中,我们创建了一个新的线程来运行hello
函数,并在主线程中通过join()
等待新线程结束。
2. 互斥量(std::mutex)
C++11的std::mutex
类提供了对操作系统原生互斥量的封装。你可以使用互斥量来保护共享数据,防止多个线程同时访问。
#include <mutex>
#include <thread>std::mutex mtx; // 全局互斥量void print_block(int n, char c) {mtx.lock();for (int i=0; i<n; ++i) { std::cout << c; }std::cout << '\n';mtx.unlock();
}int main() {std::thread th1(print_block,50,'*');std::thread th2(print_block,50,'$');th1.join();th2.join();return 0;
}
在这个例子中,我们使用互斥量mtx
来保护std::cout
,防止两个线程同时输出。
3. 条件变量(std::condition_variable)
C++11的std::condition_variable
类提供了对操作系统原生条件变量的封装。你可以使用条件变量来实现线程间的同步。
#include <iostream>
#include <thread>
#include <mutex>
#include <condition_variable>std::mutex mtx;
std::condition_variable cv;
bool ready = false;void print_id(int id) {std::unique_lock<std::mutex> lck(mtx);while (!ready) cv.wait(lck);std::cout << "thread " << id << '\n';
}void go() {std::unique_lock<std::mutex> lck(mtx);ready = true;cv.notify_all();
}int main() {std::thread threads[10];for (int i=0; i<10; ++i)threads[i] = std::thread(print_id,i);std::cout << "10 threads ready to race...\n";go();for (auto& th : threads) th.join();return 0;
}
在这个例子中,我们使用条件变量cv
来实现10个线程的同步。当go
函数被调用时,所有等待在cv
上的线程都会被唤醒。
4. Future(std::future)
C++11的std::future
类提供了一种表示异步操作结果的方式。你可以使用std::async
函数来启动一个异步操作,并返回一个std::future
对象。然后你可以在任何时候通过std::future::get
函数来获取异步操作的结果。
#include <iostream>
#include <future>int factorial(int n) {int res = 1;for(int i = n; i > 1; --i)res *= i;return res;
}int main() {std::future<int> fut = std::async(factorial, 5);std::cout << "Factorial of 5 is " << fut.get() << std::endl;return 0;
}
在这个例子中,我们使用std::async
启动了一个异步操作来计算5的阶乘,并通过std::future::get
获取了结果。
相关文章:

《C++11》并发库:简介与应用
在C11之前,C并没有提供原生的并发支持。开发者通常需要依赖于操作系统的API(如Windows的CreateThread或POSIX的pthread_create)或者第三方库(如Boost.Thread)来创建和管理线程。这些方式存在以下几个问题: …...

LeetCode - #183 Swift 实现查询未下订单的客户
网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…...

HTML拖拽功能(纯html5+JS实现)
1、HTML拖拽--单元行拖动 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Document</title><…...

mysql 等保处理,设置wait_timeout引发的问题
👨⚕ 主页: gis分享者 👨⚕ 感谢各位大佬 点赞👍 收藏⭐ 留言📝 加关注✅! 👨⚕ 收录于专栏:运维工程师 文章目录 前言问题处理 前言 系统部署完成后,客户需要做二级等保&…...

7.STM32F407ZGT6-RTC
参考: 1.正点原子 前言: RTC实时时钟是很基本的外设,用来记录绝对时间。做个总结,达到: 1.学习RTC的原理和概念。 2.通过STM32CubeMX快速配置RTC。 27.1 RTC 时钟简介 STM32F407 的实时时钟(RTC…...

重写(补充)
大家好,今天我们把剩下一点重写内容说完,来看。 [重写的设计规则] 对于已经投入使用的类,尽量不要进行修政 ,最好的方式是:重新定义一个新的类,来重复利用其中共性的内容 我们不该在原来的类上进行修改,因为原来的类,可能还有用…...

30分钟内搭建一个全能轻量级springboot 3.4 + 脚手架 <3>5分钟集成好druid并使用druid自带监控工具监控sql请求
快速导航 快速导航 <1> 5分钟快速创建一个springboot web项目 <2> 5分钟集成好最新版本的开源swagger ui,并使用ui操作调用接口 <3> 5分钟集成好druid并使用druid自带监控工具监控sql请求 <4> 5分钟集成好mybatisplus并使用mybatisplus g…...

【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理
【C#深度学习之路】如何使用C#实现Yolo8/11 Segment 全尺寸模型的训练和推理 项目背景项目实现推理过程训练过程 项目展望写在最后项目下载链接 本文为原创文章,若需要转载,请注明出处。 原文地址:https://blog.csdn.net/qq_30270773/article…...

Oracle 分区索引简介
目录 一. 什么是分区索引二. 分区索引的种类2.1 局部分区索引(Local Partitioned Index)2.2 全局分区索引(Global Partitioned Index) 三. 分区索引的创建四. 分区索引查看4.1 USER_IND_COLUMNS 表4.2 USER_INDEXES 表 五. 分区索…...

【科技赋能未来】NDT2025第三届新能源数字科技大会全面启动!
随着我国碳达峰目标、碳中和目标的提出,以及经济社会的发展进步,以风电、光伏发电为代表的新能源行业迎来巨大发展机遇,成为未来绿色经济发展的主要趋势和方向。 此外,数字化技术的不断发展和创新,其在新能源领域的应…...

Broker收到消息之后如何存储
1.前言 此文章是在儒猿课程中的学习笔记,感兴趣的想看原来的课程可以去咨询儒猿课堂《从0开始带你成为RocketMQ高手》,我本人觉得这个作者还是不错,都是从场景来进行分析,感觉还是挺适合我这种小白的。这块主要都是我自己的学习笔…...

Mysql--实战篇--SQL优化(查询优化器,常用的SQL优化方法,执行计划EXPLAIN,Mysql性能调优,慢日志开启和分析等)
一、查询优化 1、查询优化器 (Query Optimizer) MySQL查询优化器(Query Optimizer)是MySQL数据库管理系统中的一个关键组件,负责分析和选择最有效的执行计划来执行SQL查询。查询优化器的目标是尽可能减少查询的执行时间和资源消耗ÿ…...

BERT与CNN结合实现糖尿病相关医学问题多分类模型
完整源码项目包获取→点击文章末尾名片! 使用HuggingFace开发的Transformers库,使用BERT模型实现中文文本分类(二分类或多分类) 首先直接利用transformer.models.bert.BertForSequenceClassification()实现文本分类 然后手动实现B…...

rabbitmqp安装延迟队列
在RabbitMQ中,延迟队列是一种特殊的队列类型。当消息被发送到此类队列后,不会立即投递给消费者,而是会等待预设的一段时间,待延迟期满后才进行投递。这种队列在多种场景下都极具价值,比如可用于处理需要在特定时间触发…...

深入探讨DICOM医学影像中的MPPS服务及其具体实现
深入探讨DICOM医学影像中的MPPS服务及其具体实现 1. 引言 在医疗影像的管理和传输过程中,DICOM(数字影像和通信医学)标准发挥着至关重要的作用。除了DICOM影像的存储和传输(如影像存储SCP和影像传输SCP),…...
集合帖:区间问题
一、AcWing 803:区间合并 (1)题目来源:https://www.acwing.com/problem/content/805/ (2)算法代码:https://blog.csdn.net/hnjzsyjyj/article/details/145067059 #include <bits/stdc.h>…...

C#,入门教程(27)——应用程序(Application)的基础知识
上一篇: C#,入门教程(26)——数据的基本概念与使用方法https://blog.csdn.net/beijinghorn/article/details/124952589 一、什么是应用程序 Application? 应用程序是编程的结果。一般把代码经过编译(等)过程&#…...

迅翼SwiftWing | ROS 固定翼开源仿真平台正式发布!
经过前期内测调试,ROS固定翼开源仿真平台今日正式上线!现平台除适配PX4ROS环境外,也已实现APROS环境下的单机飞行控制仿真适配。欢迎大家通过文末链接查看项目地址以及具体使用手册。 1 平台简介 ROS固定翼仿真平台旨在实现固定翼无人机决策…...
CSS 样式 box-sizing: border-box; 详细解读
box-sizing是 CSS 中的一个属性,用于控制元素的盒模型计算方式。border-box值表示元素的宽度和高度将包括内边距(padding)和边框(border),而不仅仅是内容的宽度和高度。这意味着当你为元素设置宽度和高度时…...
FLASK创建下载
html用a标签 <!-- Button to download the image --> <a href"{{ url_for(download_file, filenameimage.png) }}"><button>Download Image</button> </a> 后端:url_for双大括号即是用来插入变量到模板中的语法。也就是绑…...

漫话架构师|什么是系统架构设计师(开篇)
~犬📰余~ “我欲贱而贵,愚而智,贫而富,可乎? 曰:其唯学乎” 关注犬余,共同进步 技术从此不孤单...

Web Socket
Web Socket WebSocket是一种基于TCP的网络通信协议,允许客户端和服务器之间建立全双工(双向)通信通道。WebSocket通过HTTP协议进行握手,建立连接后,客户端和服务器可以在同一个连接上同时发送和接收数据࿰…...

JavaSE学习心得(反射篇)
反射 前言 获取class对象的三种方式 利用反射获取构造方法 利用反射获取成员变量 利用反射获取成员方法 练习 保存信息 跟配置文件结合动态创建 前言 接上期文章:JavaSE学习心得(多线程与网络编程篇) 教程链接:黑马…...

使用FRP进行内网穿透
一、基本概念 内网穿透:它是一种网络技术或方法,旨在允许外部网络(如互联网)访问位于内部网络(内网)中的设备或服务。由于内部网络通常处于NAT(网络地址转换)、防火墙或其他安全机制…...
长安“战疫”网络安全公益赛的一些随想
起因 今年刚进入大学,开始带校队,为了培养校队新成员,也就一直计划着和当地的一些高校合作交流,但是由于种种原因一直被搁置下来。正巧学校信息中心和四叶草有一个培训项目的合作,学校的网安协会也算是沾了光成为了培…...
flutter 安卓端打包
在 Flutter 中打包 Android 应用程序是一个相对简单的过程。你可以使用 Flutter 的命令行工具来构建并打包你的 APK 或 AAB(Android App Bundle)。以下是打包 Flutter Android 应用的步骤: 1. 安装 Flutter 环境 确保你已经安装了 Flutter …...
Cesium中的CustomDataSource 详解
Cesium CustomDataSource 详解 在 Cesium 中,CustomDataSource 是一个强大的类,用于处理自定义的地理数据。它提供了一种方法,可以通过程序方式添加、管理和更新动态的地理实体,而无需依赖外部数据格式(如 GeoJSON 或…...

[Qt]常用控件介绍-按钮类控件-QPushButton、QRedioButton、QCheckBox、QToolButton控件
目录 1.QPushButton按钮 介绍 属性 Demo:键盘方向键控制人物移动 2.Redio Button按钮 属性 clicked、pressed、released、toggled区别 单选按钮的分组 Demo:点餐小程序 3.CheckBox按钮 属性 Demo:获取今天的形成计划 4.ToolBu…...
Windows 蓝牙驱动开发-安装蓝牙设备
蓝牙配置文件驱动程序有两种安装类型: 客户端安装,在此类安装中,远程设备播发其服务,并且计算机与之连接。 示例包括:鼠标、键盘和打印机;服务器端安装,在此类安装中,计算机播发服务…...

element表格有横向滚动条时产生错位或者偏移(火狐浏览器)
问题图 解决方法:给表头增加竖向滚动条的宽度 // 解决拖拽表格滚动条,错位问题 ::v-deep .el-table__header-wrapper{padding-right: 20px!important; // 滚动条宽度 }效果图如下:...