C++多线程编程(一) thread类初窥
多线程编程使我们的程序能够同时执行多项任务。
在C++11以前,C++没有标准的多线程库,只能使用C语言中的pthread,在C++11之后,C++标准库中增加了thread类用于多线程编程。thread类其实是对pthread的封装,不过更加好用,现在已经广泛用于C++多线程编程。
C++11的多线程库主要包含<thread> <mutex> <atomic> <condition_variable> <future>等头文件,这篇文章只要整理记录<thread>头文件的内容。
<thread>头文件中主要就是定义了thread类,thread主要的public接口有以下几个:

1. 构造函数---创建线程
thread类提供了默认构造函数,移动构造函数和一般构造函数,并且禁止编译器生成拷贝构造函数,以及重载 = 操作符,这俩是不允许的。
三种构造函数的原型:
//默认构造
thread() noexcept = default;
//移动构造
thread(thread&& __t) noexcept;
//一般构造
template<typename _Callable, typename... _Args>
explicit thread(_Callable&& __f, _Args&&... __args);
最常用的是一般构造函数,使用一般构造函数创建线程,需要传入一个入口函数,和这个函数需要的参数,说白了就是告诉被创建的线程要去做什么事情,如果这个线程有形参,需要跟在后边一起传入。
#include <unistd.h>
#include <thread>void fun(int num) {while (num--){sleep(1);std::cout << "thread th " << num << std::endl;}
}int main() {std::thread th(fun, 3);if (th.joinable()){th.join();}}
上边的例子中std::thread th(fun, 3);创建了一个线程,线程的入口函数就是void fun(int num)这个函数,开启线程的时候,同时需要把fun需要的参数传进去。
2. get_id
每个线程都有一个唯一的标识符,即线程id,使用get_id函数可以获取线程的id;
get_id返回一个类型为std::thread::id的对象,这是一个类,它对<<运算符进行了重载,所以可以直接用std::cout打印出来。
#include <unistd.h>
#include <thread>void fun(int num) {while (num--){
// sleep(1);
// std::cout << "thread th " << num << std::endl;}
}
int main() {std::thread th(fun, 3);std::cout << th.get_id() << std::endl;std::cout << this_thread::get_id() << std::endl;if (th.joinable()){th.join();}
}

this_thread是一个命名空间,表示当前线程,当前线程就是main函数所在的主线程,所以thread::get_id()在这里就是主线程的id。
3. join & detach
void join();
void detach();
第一个例子中,线程开启之后,有这样一段代码
if (th.joinable())
{th.join();
}
这段代码意思是等待th线程执行完毕,主线程再继续往下执行。
如果把这段代码注释掉,会得到这样的结果

这是因为th线程尚未执行完毕,主线程就退出了,所以th线程被强行中断了,而且终端会打印一段错误信息(terminate called without an active exception) 。
join 和 detach 是线程两种不同的运行方式:
- join表示等待,调用后会阻塞当前线程,直到join线程执行完毕,调用者才继续往下执行;
- detach表示分离,程序不会等待detach线程执行完,且程序退出之后,detach线程由系统接管继续执行。
4. joinable
bool joinable() const noexcept;
在调用join或者detach之前,先判断线程是否joinable,是一个良好的习惯。
从一般构造函数创建的线程,他们的joinable都是ture,可以进行join或者detach,而且,对线程进行join和detah是必要的,这样可以明确告诉程序,该怎么调度这个线程,避免不必要的错误发生。
具体原因可以看这里。
5. 析构函数
~thread()
{if (joinable()){std::terminate();}}
从析构函数可以看出来,如果一个线程在释放的时候还是joinable的,那么整个程序都会退出,这也是为什么线程一定要调用join或者detach的原因,调用了join和detach之后,线程的joinable就为false了。
上边说到join和detach的时候,尝试把join删掉了,确实会导致程序报错。
6. swap
void swap (thread& x) noexcept;
交换两个线程的所有属性。
相关文章:
C++多线程编程(一) thread类初窥
多线程编程使我们的程序能够同时执行多项任务。 在C11以前,C没有标准的多线程库,只能使用C语言中的pthread,在C11之后,C标准库中增加了thread类用于多线程编程。thread类其实是对pthread的封装,不过更加好用ÿ…...
Qt QVector 详解:从底层原理到高级用法
目录标题 引言:QVector的重要性与简介QVector的常用接口QVector和std::Vector迭代器:遍历QVector 中的元素(Iterators: Traversing Elements in QVector)常规索引遍历基于范围的for循环(C11及以上)使用STL样…...
快速弄懂RPC
快速弄懂RPC 常见的远程通信方式远程调用RPC协议RPC的运用场景和优势 常见的远程通信方式 基于REST架构的HTTP协议以及基于RPC协议的RPC框架。 远程调用 是指跨进程的功能调用。 跨进程可以理解为一个计算机节点的多个进程或者多个计算机节点的多个进程。 RPC协议 远程过…...
ONVIF协议介绍
目录标题 一、 ONVIF协议简介(Introduction to ONVIF Protocol)1.1 ONVIF的发展历程(The Evolution of ONVIF)1.2 ONVIF的主要作用与优势(The Main Functions and Advantages of ONVIF) 二、 ONVIF协议的底…...
AI大模型内卷加剧,商汤凭什么卷进来
2023年,国内大模型何其多。 目前,已宣布推出或即将推出大模型的国内企业多达20余家,基本上能想到的相关企业都已入局。其中,既有资金雄厚的BAT、华为、字节等大厂,也有王慧文、王小川、周伯文等互联网大佬领衔的初创企…...
企业网络安全漏洞分析及其解决_kaic
摘要 为了防范网络安全事故的发生,互联网的每个计算机用户、特别是企业网络用户,必须采取足够的安全防护措施,甚至可以说在利益均衡的情况下不惜一切代价。事实上,许多互联网用户、网管及企业老总都知道网络安全的要性,却不知道网…...
Docker网络模式与cgroups资源控制
目录 1.docker网络模式原理 2.端口映射 3.Docker网络模式(41种) 1.查看docker网络列表 2.网络模式详解 4.Docker cgroups资源控制 1.CPU资源控制 2.对内存使用的限制 3.对磁盘IO的配置控制(blkio)的限制 4.清除docker占用…...
Linux/C++:基于TCP协议实现网络版本计算器(自定义应用层协议)
目录 Sock.hpp TcpServer.hpp Protocol.hpp CalServer.cc CalClient.cc 分析 因为,TCP面向字节流,所以TCP有粘包问题,故我们需要应用层协议来区分每一个数据包。防止读取到半个,一个半数据包的情况。 Sock.hpp #pragma on…...
并发之阻塞队列
阻塞队列 使用背景作用从阻塞队列中获取元素常用的三个方法往阻塞队列中存放元素的三种方式 使用背景 想要在多个线程之间传递数据,用一般的对象是不行的,比如我们常用的ArrayList和HashMap都不适合由多个线程同时操作,可能会造成数据丢失或…...
nodejs+vue 智能餐厅菜品厨位分配管理系统
系统功能主要介绍以下几点: 本智能餐厅管理系统主要包括三大功能模块,即用户功能模块和管理员功能模块、厨房功能模块。 (1)管理员模块:系统中的核心用户是管理员,管理员登录后,通过管理员功能来…...
MySQL NULL 值
NULL 值是遗漏的未知数据,默认地,表的列可以存放 NULL 值。 本章讲解 IS NULL 和 IS NOT NULL 操作符。 如果表中的某个列是可选的,那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。 N…...
Python 机器人学习手册:1~5
原文:ILearning Robotics using Python 协议:CC BY-NC-SA 4.0 译者:飞龙 本文来自【ApacheCN 计算机视觉 译文集】,采用译后编辑(MTPE)流程来尽可能提升效率。 当别人说你没有底线的时候,你最好…...
OpenCV(14)-OpenCV4.0中文文档学习2(补充)
相机校准和3D重建 相机校准 标定 findChessboardCorners() 它返回角点和阈值,如果成功找到所有角点,则返回 True。这些角落将按顺序放置(从左到右,从上到下)cornerSubPix()用以寻找图案,找到角点后也可以…...
八、express框架解析
文章目录 前言一、express 路由简介1、定义2、基础使用 二、express 获取参数1、获取请求报文参数2、获取路由参数 三、express 响应设置1、一般响应设置2、其他响应设置 四、express 防盗链五、express 路由模块化1、模块中代码如下:2、主文件中代码如下࿱…...
SpringBoot整合接口管理工具Swagger
Swagger Swagger简介 Springboot整合swagger Swagger 常用注解 一、Swagger简介 Swagger 是一系列 RESTful API 的工具,通过 Swagger 可以获得项目的⼀种交互式文档,客户端 SDK 的自动生成等功能。 Swagger 的目标是为 REST APIs 定义一个标…...
50+常用工具函数之xijs更新指南(v1.2.3)
xijs 是一款开箱即用的 js 业务工具库, 聚集于解决业务中遇到的常用的js函数问题, 帮助开发者更高效的进行业务开发. 目前已聚合了50常用工具函数, 接下来就和大家一起分享一下v1.2.3 版本的更新内容. 1. 添加将树结构转换成扁平数组方法 该模块主要由 EasyRo 贡献, 添加内容如…...
【DAY42】vue学习
const routes [ { path: ‘/foo’, component: Foo }, { path: ‘/bar’, component: Bar } ]定义路由的作用是什么 const routes 定义路由的作用是将每一个 URL 请求映射到一个组件,其中 path 表示请求的 URL,component 表示对应的组件。 通过 const…...
JavaScript小记——事件
HTML 事件是发生在 HTML 元素上的事情。 当在 HTML 页面中使用 JavaScript 时, JavaScript 可以触发这些事件。 Html事件 HTML 事件可以是浏览器行为,也可以是用户行为。 以下是 HTML 事件的实例: HTML 页面完成加载HTML input 字段改变…...
Windows逆向安全(一)之基础知识(八)
if else嵌套 这次来研究if else嵌套在汇编中的表现形式,本次以获取三个数中最大的数这个函数为例子,分析if else的汇编形式 求三个数中的最大值 首先贴上代码: #include "stdafx.h"int result0; int getMax(int i,int j,int k)…...
PyCharm+PyQt5+pyinstaller打包labelImg.exe
0 开头 labelImg是一款标注软件,作为一个开源项目,它的源码可以在github上找到。官方仓库地址为: https://github.com/heartexlabs/labelImg 小白安装时的最新版本编译出来的界面长这样: 之前在小白的博客里,也教过…...
测试微信模版消息推送
进入“开发接口管理”--“公众平台测试账号”,无需申请公众账号、可在测试账号中体验并测试微信公众平台所有高级接口。 获取access_token: 自定义模版消息: 关注测试号:扫二维码关注测试号。 发送模版消息: import requests da…...
Vue记事本应用实现教程
文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展:显示创建时间8. 功能扩展:记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
多模态商品数据接口:融合图像、语音与文字的下一代商品详情体验
一、多模态商品数据接口的技术架构 (一)多模态数据融合引擎 跨模态语义对齐 通过Transformer架构实现图像、语音、文字的语义关联。例如,当用户上传一张“蓝色连衣裙”的图片时,接口可自动提取图像中的颜色(RGB值&…...
微信小程序云开发平台MySQL的连接方式
注:微信小程序云开发平台指的是腾讯云开发 先给结论:微信小程序云开发平台的MySQL,无法通过获取数据库连接信息的方式进行连接,连接只能通过云开发的SDK连接,具体要参考官方文档: 为什么? 因为…...
Python ROS2【机器人中间件框架】 简介
销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
【JavaSE】多线程基础学习笔记
多线程基础 -线程相关概念 程序(Program) 是为完成特定任务、用某种语言编写的一组指令的集合简单的说:就是我们写的代码 进程 进程是指运行中的程序,比如我们使用QQ,就启动了一个进程,操作系统就会为该进程分配内存…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
