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 小白安装时的最新版本编译出来的界面长这样: 之前在小白的博客里,也教过…...
大数据学习栈记——Neo4j的安装与使用
本文介绍图数据库Neofj的安装与使用,操作系统:Ubuntu24.04,Neofj版本:2025.04.0。 Apt安装 Neofj可以进行官网安装:Neo4j Deployment Center - Graph Database & Analytics 我这里安装是添加软件源的方法 最新版…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
【算法训练营Day07】字符串part1
文章目录 反转字符串反转字符串II替换数字 反转字符串 题目链接:344. 反转字符串 双指针法,两个指针的元素直接调转即可 class Solution {public void reverseString(char[] s) {int head 0;int end s.length - 1;while(head < end) {char temp …...
在Ubuntu中设置开机自动运行(sudo)指令的指南
在Ubuntu系统中,有时需要在系统启动时自动执行某些命令,特别是需要 sudo权限的指令。为了实现这一功能,可以使用多种方法,包括编写Systemd服务、配置 rc.local文件或使用 cron任务计划。本文将详细介绍这些方法,并提供…...
PL0语法,分析器实现!
简介 PL/0 是一种简单的编程语言,通常用于教学编译原理。它的语法结构清晰,功能包括常量定义、变量声明、过程(子程序)定义以及基本的控制结构(如条件语句和循环语句)。 PL/0 语法规范 PL/0 是一种教学用的小型编程语言,由 Niklaus Wirth 设计,用于展示编译原理的核…...
有限自动机到正规文法转换器v1.0
1 项目简介 这是一个功能强大的有限自动机(Finite Automaton, FA)到正规文法(Regular Grammar)转换器,它配备了一个直观且完整的图形用户界面,使用户能够轻松地进行操作和观察。该程序基于编译原理中的经典…...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
【Redis】笔记|第8节|大厂高并发缓存架构实战与优化
缓存架构 代码结构 代码详情 功能点: 多级缓存,先查本地缓存,再查Redis,最后才查数据库热点数据重建逻辑使用分布式锁,二次查询更新缓存采用读写锁提升性能采用Redis的发布订阅机制通知所有实例更新本地缓存适用读多…...
深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向
在人工智能技术呈指数级发展的当下,大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性,吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型,成为释放其巨大潜力的关键所在&…...
