《C++并发编程实战》笔记(一、二)
一、简介
抽象损失:对于实现某个功能时,可以使用高级工具,也可以直接使用底层工具。这两种方式运行的开销差异称为抽象损失。
二、线程管控
2.1 线程的基本控制
1. 创建线程
线程相关的管理函数和类在头文件:
#include <thread>
创建一个线程使用如下方法:
std::thread t(callable);
callable
:线程函数,可以是任意的可调用对象- 线程对象创建后会立即启动线程运行
2. 控制线程的结束
线程启动后,必须显式指定线程结束的方式:
阻塞等待其结束(汇合),使用如下方法:
t.join();
- 只要调用了
join()
,主线程会阻塞等待该线程执行结束,join()
执行结束后,隶属于该线程的任何存储空间都会被清除,且线程对象不再关联到结束的线程 - 成员函数
t.joinable()
返回线程对象t
是否关联到某个线程,当join()
执行结束后t.joinable()
会返回false
- 只有关联到某个线程的对象才能调用
join()
让线程后台运行(分离),使用如下方法:
t.detach();
- 线程对象必须关联某个线程(
joinable()
为true
时)才能调用detach
,调用后线程的归属权和控制权都转移给C++运行时库,它独立于主线程继续运行,直至线程函数运行结束,且C++运行时库会保证线程退出后与之关联的资源都被正确回收 - 被
detach
的线程不再关联实际的执行线程(joinable()
会返回false
),所以不可再调用join()
注意:如果线程对象销毁时都没有指定结束方式,则std::thread
的析构函数会调用std::terminate()
终止整个程序
3. 异常时保证线程正常结束
创建线程对象后,如果在指定线程结束方式前,因为执行其他代码造成了异常,可能会导致指定线程结束方式的代码被略过,从而导致程序终止。即:
void func() {try {// 线程 t 去执行 do_something() 函数std::thread t(do_something);// 此时如果发生异常等,下面的join可能无法被调用,退出func时程序会被中断do_other_thing();} catch (...) {throw;}t.join();return;
}
解决方法:
- 一种解决方法是保证在程序的所有执行路径都会指定线程结束方式
void func() {try {std::thread t(do_something);do_other_thing();} catch (...) {// 保证一定会指定线程结束方式t.join();throw;}t.join();return; }
- 使用RAII方法,利用对象管理线程,在构造函数中创建线程,在析构函数中指定线程的结束方式
class RaiiThreadGuard {public:explicit RaiiThreadGuard(std::thread &t) : t_(t) {} ~RaiiThreadGuard() {// 类对象离开作用域时一定会调用析构,保证一定会指定线程对象的结束方式t_.join();}// 将拷贝构造和拷贝赋值都定义为删除的,避免编译器优化造成重复调用析构RaiiThreadGuard(const RaiiThreadGuard &) = delete;RaiiThreadGuard& operator=(const RaiiThreadGuard &) = delete;private:std::thread& t_; };// main 函数中通过如下方式使用 int main() {// 创建线程std::thread t(HelloFunction);// 使用 RAII 保证线程对象一定会调用 joinRaiiThreadGuard thread_guard(t);// 即使后续再执行其他代码造成退出作用域,编译器会保证执行 thread_guard 的析构指定线程的结束方式return 0; }
2.2 向线程函数传递参数
线程函数所需要的参数可以直接紧跟在std::thread
的线程函数实参后:
- 线程具有内部存储空间,线程函数的实参会先使用拷贝构造函数,将
std::thread
的实参复制到创建的线程;在创建好的线程中,新复制出来的实参被当成临时量,以右值形式传递给新线程中的线程函数 - 根据参数的传递过程,如果线程函数包含非const引用形参,为避免在线程内执行时收到右值,需要通过
std::ref
在std::thread
传递实参(与std::bind
函数的使用相同) - 类的非静态成员函数第一个参数是指向对象的隐式
this
指针,如果想在线程中执行某个成员函数,需要将对象地址传递给成员函数的隐式this
指针
class TestClass {
public:/** @brief 默认构造函数 */TestClass(){std::cout << "TestClass default constructor." << std::endl;std::cout << "std::thread::id: " << std::this_thread::get_id() << std::endl;}/** @brief 拷贝构造函数 */TestClass(const TestClass& ohter) {std::cout << "TestClass copy constructor." << std::endl;std::cout << "std::thread::id: " << std::this_thread::get_id() << std::endl;}/** @brief 移动构造函数 */TestClass(TestClass&& ohter) {std::cout << "TestClass move constructor." << std::endl;std::cout << "std::thread::id: " << std::this_thread::get_id() << std::endl;}/** @brief 类的内部函数 */void InnerFunction() {std::cout << "TestClass Inner Function." << std::endl;std::cout << "std::thread::id: " << std::this_thread::get_id() << std::endl;}
};void func(int num, std::string &str, TestClass obj) {str += std::to_string(num);
}// main 函数
std::string str("The num: ");
TestClass test_class;
// 参数直接作为 std::thread 的后续参数传入
// 1. 对象会先调用拷贝构造复制到线程,再通过std::move()以右值复制给线程内的函数形参
// 2. 线程函数的引用形参要通过 std::ref() 传递
std::thread t(func, 3, std::ref(str), test_class);
t.join();
std::cout << str << std::endl;// 在线程中运行类的成员函数,需要将对象的地址传递给成员函数的隐式this指针
std::thread t2(&TestClass::InnerFunction, &test_class);
t2.join();/* 输出
TestClass default constructor.
std::thread::id: 140737348195264
TestClass copy constructor.
std::thread::id: 140737348195264
TestClass move constructor.
std::thread::id: 140737348179520
The num: 3
TestClass Inner Function.
std::thread::id: 140737348179520
*/
2.3 转移线程归属权
在某些情况下,如想要指定特定的函数等待线程结束,可能需要转移线程的归属权。
std::thread
与std::unique
类似,由于独占资源,其对象不能被复制,只支持移动:
std::thread t1(some_function);
std::thread t2 = std::move(t1);
2.4 运行时确定线程数量
标准库的静态函数std::thread::hardware_concurrency()
函数返回程序在执行时可以真正并发的线程数量:
- 若信息无法获取,返回0
- 否则返回支持并发的线程数
2.5 标识不同线程
每个线程都有一个唯一的ID,该ID是一个std::thread::id
类型的变量:
- 可以使用线程对象的
std::thread::get_id()
函数返回线程对象的ID - 在程序中可以使用
std::this_thread::get_id()
函数获取运行当前程序的线程ID - 默认构造创建的
std::thread::id
类型变量表示线程不存在
std::thread::joinable()
函数会利用线程对象的ID确定返回值,即:
- 若
this.get_id() != std::thread::id()
则返回 true(判断当前线程ID和默认构造的线程ID类型变量是否相同) - 否则返回false(表示线程对象没有关联到任何线程,线程不存在)
相关文章:
![](https://www.ngui.cc/images/no-images.jpg)
《C++并发编程实战》笔记(一、二)
一、简介 抽象损失:对于实现某个功能时,可以使用高级工具,也可以直接使用底层工具。这两种方式运行的开销差异称为抽象损失。 二、线程管控 2.1 线程的基本控制 1. 创建线程 线程相关的管理函数和类在头文件: #include <…...
![](https://www.ngui.cc/images/no-images.jpg)
【日常bug记录】el-checkbox 绑定对象数组
版本说明 "vue": "2.6.10", "element-ui": "2.13.2", 这个写法很怪异哦,但确实管用。el-checkbox 绑定的 label 是双向绑定的值,也就是选中之后传到表单数据里面的值,一般设置为 id,然后…...
![](https://img-blog.csdnimg.cn/img_convert/1e9255ff6a498fe5dc8832f24e811bf5.png)
单元测试Mockito笔记
文章目录 单元测试Mockito1. 入门1.1 什么是Mockito1.2 优势1.3 原理 2. 使用2.0 环境准备2.1 Mock1) Mock对象创建2) 配置Mock对象的行为(打桩)3) 验证方法调用4) 参数匹配5) 静态方法 2.2 常用注解1) Mock2) BeforeEach 与 BeforeAfter3) InjectMocks4) Spy5) Captor6) RunWi…...
![](https://i-blog.csdnimg.cn/direct/c98984feed6d4d628ce95ec02a7c57a4.png)
基于SpringBoot+VueJS+微信小程序技术的图书森林共享小程序设计与实现:7000字论文+源代码参考
博主介绍:硕士研究生,专注于信息化技术领域开发与管理,会使用java、标准c/c等开发语言,以及毕业项目实战✌ 从事基于java BS架构、CS架构、c/c 编程工作近16年,拥有近12年的管理工作经验,拥有较丰富的技术架…...
![](https://i-blog.csdnimg.cn/direct/9e60f530858f4b4f995f6389966b2118.png)
GitHub连接超时问题 Recv failure: Connection was reset
用手机热点WIF拉取git项目的时候,遇到Recv failure: Connection was reset问题。 解决办法 一、手动开启本地代理 二、在终端(cmd)输入命令 git config --global http.proxy http://127.0.0.1:7890 git config --global https.proxy https:…...
![](https://www.ngui.cc/images/no-images.jpg)
浅谈PostCSS
1. 背景 css的预处理器语言(比如 sass, less, stylus)的扩展性不好,你可以使用它们已有的功能,但如果想做扩展就没那么容易。 sass是很常用的css预处理器语言,在webpack中要使用它,…...
![](https://www.ngui.cc/images/no-images.jpg)
GCN、GIN
# 使用TuDataset 中的PROTEINS数据集。 # 里边有1113个蛋白质图,区分是否为酶,即二分类问题。# 导包 from torch_geometric.datasets import TUDataset from torch_geometric.data import DataLoader import torch import torch.nn as nn import torch.…...
![](https://www.ngui.cc/images/no-images.jpg)
Web控件进阶交互
Web控件进阶交互 测试时常需要模拟键盘或鼠标操作,可以用Python的ActionChains来模拟。ActionChains是Selenium提供的一个子类,用于生成和执行复杂的用户交互操作,允许将一系列操作链接在一起,然后一次性执行。 from selenium im…...
![](https://img-blog.csdnimg.cn/img_convert/98cc41498bd6285e0e07bbbcae53d1aa.png)
基于SpringBoot的校园疫情防控系统
你好,我是专注于计算机科学与技术的研究者。如果你对我的工作感兴趣或有任何问题,欢迎随时联系我。 开发语言:Java 数据库:MySQL 技术:SpringBoot框架,B/S架构 工具:Eclipse,Mav…...
![](https://i-blog.csdnimg.cn/direct/726c6358bd864c3180be3bfb5890621f.png)
elasticsearch 查询超10000的解决方案
前言 默认情况下,Elasticsearch集群中每个分片的搜索结果数量限制为10000。这是为了避免潜在的性能问题。 但是我们 在实际工作过程中时常会遇到 需要深度分页,以及查询批量数据更新的情况 问题:当请求form size >10000 时,…...
![](https://i-blog.csdnimg.cn/direct/b1cd87a7e82f4de2be91e4df2216cd52.png)
SpringCloud集成kafka集群
目录 1.引入kafka依赖 2.在yml文件配置配置kafka连接 3.注入KafkaTemplate模版 4.创建kafka消息监听和消费端 5.搭建kafka集群 5.1 下载 kafka Apache KafkaApache Kafka: A Distributed Streaming Platform.https://kafka.apache.org/downloads.html 5.2 在config目录下做…...
![](https://i-blog.csdnimg.cn/direct/c3aeb48cb60a4466aec5c1ea564be8ff.png)
Macos 远程登录 Ubuntu22.04 桌面
这里使用的桌面程序为 xfce, 而 gnome 桌面则测试失败。 1,安装 在ubuntu上,安装 vnc server与桌面程序xfce sudo apt install xfce4 xfce4-goodies tightvncserver 2,第一次启动和配置 $ tightvncserver :1 设置密码。 然后修改配置:…...
![](https://www.ngui.cc/images/no-images.jpg)
第十届MathorCup高校数学建模挑战赛-A题:无车承运人平台线路定价问题
目录 摘 要 1 问题重述 1.1 研究背景 1.2 研究问题 2 符号说明与模型假设 2.1 符号说明 2.2 模型假设 3 问题一:模型建立与求解 3.1 问题分析与思路 3.2 模型建立 3.2.1 多因素回归模型 3.3 模型求解 3.3.1 数据预处理 3.3.2 重要度计算 4 问题二:模型建立与求…...
![](https://i-blog.csdnimg.cn/direct/e2a5dff72bcf4242b473e5bbd0ab7134.png)
在分布式环境中,怎样保证 PostgreSQL 数据的一致性和完整性?
文章目录 在分布式环境中保证 PostgreSQL 数据的一致性和完整性一、数据一致性和完整性的重要性二、分布式环境对数据一致性和完整性的挑战(一)网络延迟和故障(二)并发操作(三)数据分区和复制 三、保证 Pos…...
![](https://www.ngui.cc/images/no-images.jpg)
RabbitMq如何保证消息的可靠性和稳定性
RabbitMq如何保证消息的可靠性和稳定性 rabbitMq不会百分之百让我们的消息安全被消费,但是rabbitMq提供了一些机制来保证我们的消息可以被安全的消费。 消息确认 消息者在成功处理消息后可以发送确认(ACK)给rabbitMq,通知消息已…...
![](https://i-blog.csdnimg.cn/direct/3ec548a611b94e72845d5fa08cac7548.png)
druid(德鲁伊)数据线程池连接MySQL数据库
文章目录 1、druid连接MySQL2、编写JDBCUtils 工具类 1、druid连接MySQL 初学JDBC时,连接数据库是先建立连接,用完直接关闭。这就需要不断的创建和销毁连接,会消耗系统的资源。 借鉴线程池的思想,数据连接池就这么被设计出来了。…...
![](https://i-blog.csdnimg.cn/direct/fc122e97eb034bae830e7dd67463cb33.png)
观察者模式的实现
引言:观察者模式——程序中的“通信兵” 在现代战争中,通信是胜利的关键。信息力以网络、数据、算法、算力等为底层支撑,在现代战争中不断推动感知、决策、指控等各环节产生量变与质变。在软件架构中,观察者模式扮演着类似的角色…...
![](https://www.ngui.cc/images/no-images.jpg)
Eureka: Netflix开源的服务发现框架
在微服务架构中,服务发现是一个关键组件,它允许服务实例之间相互发现并进行通信。Eureka是由Netflix开源的服务发现框架,它是Spring Cloud体系中的核心组件之一。Eureka提供了服务注册与发现的功能,支持区域感知和自我保护机制&am…...
![](https://www.ngui.cc/images/no-images.jpg)
go-基准测试
基准测试 Demo // fib_test.go package mainimport "testing"func BenchmarkFib(b *testing.B) {for n : 0; n < b.N; n {fib(30) // run fib(30) b.N times} }func fib(n int) int {if n 0 || n 1 {return n}return fib(n-2) fib(n-1) }benchmark 和普通的单…...
![](https://i-blog.csdnimg.cn/direct/57e2bb8ce3884877a6c6353ca79a48f0.png#pic_center)
线性代数|机器学习-P23梯度下降
文章目录 1. 梯度下降[线搜索方法]1.1 线搜索方法,运用一阶导数信息1.2 经典牛顿方法,运用二阶导数信息 2. hessian矩阵和凸函数2.1 实对称矩阵函数求导2.2. 线性函数求导 3. 无约束条件下的最值问题4. 正则化4.1 定义4.2 性质 5. 回溯线性搜索法 1. 梯度…...
![](https://i-blog.csdnimg.cn/direct/86bbaac78e164685bb59ddf3c281c19a.png)
SQL,python,knime将数据混合的文字数字拆出来,合并计算实战
将下面将数据混合的文字数字拆出来,合并计算 一、SQL解决: ---创建表插入数据 CREATE TABLE original_data (id INT AUTO_INCREMENT PRIMARY KEY,city VARCHAR(255),value DECIMAL(10, 2) );INSERT INTO original_data (city, value) VALUES (上海0.5…...
![](https://www.ngui.cc/images/no-images.jpg)
mac ssh连接工具
在Mac上,有多个SSH连接工具可供选择,这些工具根据其功能和适用场景的不同,可以满足不同用户的需求。以下是一些推荐的SSH客户端软件:12 iTerm2:这是一款功能强大的终端应用程序,提供了丰富的功能和定制选项…...
![](https://img-blog.csdnimg.cn/img_convert/6f634429a6f2d3a7a211da63c63c574e.jpeg)
阿里通义音频生成大模型 FunAudioLLM 开源
简介 近年来,人工智能(AI)技术的进步极大地改变了人类与机器的互动方式,特别是在语音处理领域。阿里巴巴通义实验室最近开源了一个名为FunAudioLLM的语音大模型项目,旨在促进人类与大型语言模型(LLMs&…...
![](https://img-blog.csdnimg.cn/img_convert/115ccdbedea07dad97b5fe00203d2539.png)
通用详情页的打造
背景介绍 大家都知道,详情页承载了站内的核心流量。它的量级到底有多大呢? 我们来看一下,日均播放次数数亿次,这么大的流量,其重要程度可想而知。 在这样一个页面,每一个功能都是大量业务的汇总点。 作为…...
![](https://img-blog.csdnimg.cn/20200927163243947.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNTkzNjQ2,size_16,color_FFFFFF,t_70#pic_center)
java内部类的本质
定义在类内部,可以实现对外部完全隐藏,可以有更好的封装性,代码实现上也往往更为简洁。 内部类可以方便地访问外部类的私有变量,可以声明为private从而实现对外完全隐藏。 在Java中,根据定义的位置和方式不同…...
![](https://www.ngui.cc/images/no-images.jpg)
vue3 学习笔记08 -- computed 和 watch
vue3 学习笔记08 – computed 和 watch computed computed 是 Vue 3 中用于创建计算属性的重要 API,它能够根据其它响应式数据动态计算出一个新的值,并确保在依赖数据变化时自动更新。 基本用法 squaredCount 是一个计算属性,它依赖于 count…...
![](https://img-blog.csdnimg.cn/img_convert/bdc344a6eaf788051ba00772ec781e3a.webp?x-oss-process=image/format,png)
Python-PLAXIS自动化建模技术与典型岩土工程案例
有限单元法在岩土工程问题中应用非常广泛,很多软件都采用有限单元解法。在使用各大软件进行数值模拟建模的过程中,岩土工程中的各种问题(塑性、渗流、固结、动力、稳定安全、热力TM),一步一步地搭建自己的Plaxis模型&a…...
![](https://www.ngui.cc/images/no-images.jpg)
license系统模型设计使用django models
User (用户)License (许可证)Product (产品)LicenseAssignment (许可证分配) 简单的模型定义: from django.db import models from django.contrib.auth.models import Userclass Product(models.Model):name models.CharField(max_length255)description model…...
![](https://i-blog.csdnimg.cn/direct/d550a4c218434c0ab469a2f232a3bb3f.png)
【通信协议-RTCM】MSM语句(1) - 多信号GNSS观测数据消息格式
注释: RTCM响应消息1020为GLONASS星历信息,暂不介绍,前公司暂未研发RTCM消息类型版本的DR/RTK模块,DR/RTK模块仅NMEA消息类型使用 注释: 公司使用的多信号语句类型为MSM4&MSM7,也应该是运用最广泛的语句…...
![](https://www.ngui.cc/images/no-images.jpg)
vue3-vite-pinia模板
模板说明 下载 git clone https://github.com/AIxiaoHanBao/vue-template.gitmodule参数 node版本 16 UI组件库 element-plus 持久化 pinia 网络请求 axios 路由 vue-router 使用说明 权限管理目录access资源目录assets组件目录components页面目录pages网络请求目录re…...
![](https://img-blog.csdnimg.cn/img_convert/b5117b637aace9321b5e8b13e7f02249.png)
yanderedev.wordpress/地推接单正规平台
这里是水果店早读课,水果店主同行交流圈子,持续分享,帮助新手入门。 水果店的水果去定价是比较复杂的事情,根据不同的情况去定价是常有的事情,有哪些情况需要去区别定价呢。 1、不同时期定价策略不同 同质量水果时&…...
![](https://pic002.cnblogs.com/images/2010/221871/2010122909472072.png)
域名购买方法/seo的方式包括
图象平滑的主要目的是减少图像噪声 图像噪声来自多方面,常见的噪声有以下几种: 加性噪声、乘性噪声、量化噪声、椒盐噪声 减少噪声的方法可以在空间域或是在频率域 在空间域,基本方法是求像素的平均值或中值 在频率域,运用的是低通…...
![](https://www.oschina.net/img/hot3.png)
wordpress如何开启page页面评论/抖音引流推广怎么做
2019独角兽企业重金招聘Python工程师标准>>> 概述 正则表达式是一种描述字符串结果的语法规则,是一个特定的格式化模式,可以匹配、替换、截取匹配的字符串。常用的语言基本上都有正则表达式,如JavaScript、java等。其实࿰…...
![](https://img-blog.csdnimg.cn/img_convert/e8cf115f94f99f9d7cb27e2ef4a316e8.png)
建网站前途/网络推广工作是做什么的
winter在他的《重学前端》课程中提到: 到现在为止,前端工程师已经成为研发体系中的重要岗位之一。可是,与此相对的是,我发现极少或者几乎没有大学的计算机专业愿意开设前端课程,更没有系统性的教学方案出现。大部分前端…...
![](https://img-blog.csdnimg.cn/20200610174351500.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQyODI4Mw==,size_16,color_FFFFFF,t_70)
科技网站 石家庄/苏州关键词优化排名推广
推荐教材 1、《R语言编程基础》,林智章、张良均 主编,人民邮电出版社。 2、《R语言与数据挖掘》,张良均、谢佳标、杨坦等著,机械工业出版社。 3、 《R语言基础与数据科技应用》,沈刚主编,人民邮电出版社。 4、《R语言商务数据分析实战》,韩宝国、张良均主编,人民邮电出…...
![](/images/no-images.jpg)
长春做网站的公司哪家好/怎么自己做一个网页
题目链接 题意:给你n个价格范围l,r,问最后没组价格的上下浮动能不能不超过k 思路:要让价格不超过k,设i的价格范围为L,R那么不超过k那么i1的价格范围就在L-k,Rk这个范围内,为了时他…...