当前位置: 首页 > news >正文

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以前&#xff0c;C没有标准的多线程库&#xff0c;只能使用C语言中的pthread&#xff0c;在C11之后&#xff0c;C标准库中增加了thread类用于多线程编程。thread类其实是对pthread的封装&#xff0c;不过更加好用&#xff…...

Qt QVector 详解:从底层原理到高级用法

目录标题 引言&#xff1a;QVector的重要性与简介QVector的常用接口QVector和std::Vector迭代器&#xff1a;遍历QVector 中的元素&#xff08;Iterators: Traversing Elements in QVector&#xff09;常规索引遍历基于范围的for循环&#xff08;C11及以上&#xff09;使用STL样…...

快速弄懂RPC

快速弄懂RPC 常见的远程通信方式远程调用RPC协议RPC的运用场景和优势 常见的远程通信方式 基于REST架构的HTTP协议以及基于RPC协议的RPC框架。 远程调用 是指跨进程的功能调用。 跨进程可以理解为一个计算机节点的多个进程或者多个计算机节点的多个进程。 RPC协议 远程过…...

ONVIF协议介绍

目录标题 一、 ONVIF协议简介&#xff08;Introduction to ONVIF Protocol&#xff09;1.1 ONVIF的发展历程&#xff08;The Evolution of ONVIF&#xff09;1.2 ONVIF的主要作用与优势&#xff08;The Main Functions and Advantages of ONVIF&#xff09; 二、 ONVIF协议的底…...

AI大模型内卷加剧,商汤凭什么卷进来

2023年&#xff0c;国内大模型何其多。 目前&#xff0c;已宣布推出或即将推出大模型的国内企业多达20余家&#xff0c;基本上能想到的相关企业都已入局。其中&#xff0c;既有资金雄厚的BAT、华为、字节等大厂&#xff0c;也有王慧文、王小川、周伯文等互联网大佬领衔的初创企…...

企业网络安全漏洞分析及其解决_kaic

摘要 为了防范网络安全事故的发生,互联网的每个计算机用户、特别是企业网络用户&#xff0c;必须采取足够的安全防护措施&#xff0c;甚至可以说在利益均衡的情况下不惜一切代价。事实上&#xff0c;许多互联网用户、网管及企业老总都知道网络安全的要性&#xff0c;却不知道网…...

Docker网络模式与cgroups资源控制

目录 1.docker网络模式原理 2.端口映射 3.Docker网络模式&#xff08;41种&#xff09; 1.查看docker网络列表 2.网络模式详解 4.Docker cgroups资源控制 1.CPU资源控制 2.对内存使用的限制 3.对磁盘IO的配置控制&#xff08;blkio&#xff09;的限制 4.清除docker占用…...

Linux/C++:基于TCP协议实现网络版本计算器(自定义应用层协议)

目录 Sock.hpp TcpServer.hpp Protocol.hpp CalServer.cc CalClient.cc 分析 因为&#xff0c;TCP面向字节流&#xff0c;所以TCP有粘包问题&#xff0c;故我们需要应用层协议来区分每一个数据包。防止读取到半个&#xff0c;一个半数据包的情况。 Sock.hpp #pragma on…...

并发之阻塞队列

阻塞队列 使用背景作用从阻塞队列中获取元素常用的三个方法往阻塞队列中存放元素的三种方式 使用背景 想要在多个线程之间传递数据&#xff0c;用一般的对象是不行的&#xff0c;比如我们常用的ArrayList和HashMap都不适合由多个线程同时操作&#xff0c;可能会造成数据丢失或…...

nodejs+vue 智能餐厅菜品厨位分配管理系统

系统功能主要介绍以下几点&#xff1a; 本智能餐厅管理系统主要包括三大功能模块&#xff0c;即用户功能模块和管理员功能模块、厨房功能模块。 &#xff08;1&#xff09;管理员模块&#xff1a;系统中的核心用户是管理员&#xff0c;管理员登录后&#xff0c;通过管理员功能来…...

MySQL NULL 值

NULL 值是遗漏的未知数据&#xff0c;默认地&#xff0c;表的列可以存放 NULL 值。 本章讲解 IS NULL 和 IS NOT NULL 操作符。 如果表中的某个列是可选的&#xff0c;那么我们可以在不向该列添加值的情况下插入新记录或更新已有的记录。这意味着该字段将以 NULL 值保存。 N…...

Python 机器人学习手册:1~5

原文&#xff1a;ILearning Robotics using Python 协议&#xff1a;CC BY-NC-SA 4.0 译者&#xff1a;飞龙 本文来自【ApacheCN 计算机视觉 译文集】&#xff0c;采用译后编辑&#xff08;MTPE&#xff09;流程来尽可能提升效率。 当别人说你没有底线的时候&#xff0c;你最好…...

OpenCV(14)-OpenCV4.0中文文档学习2(补充)

相机校准和3D重建 相机校准 标定 findChessboardCorners() 它返回角点和阈值&#xff0c;如果成功找到所有角点&#xff0c;则返回 True。这些角落将按顺序放置&#xff08;从左到右&#xff0c;从上到下&#xff09;cornerSubPix()用以寻找图案&#xff0c;找到角点后也可以…...

八、express框架解析

文章目录 前言一、express 路由简介1、定义2、基础使用 二、express 获取参数1、获取请求报文参数2、获取路由参数 三、express 响应设置1、一般响应设置2、其他响应设置 四、express 防盗链五、express 路由模块化1、模块中代码如下&#xff1a;2、主文件中代码如下&#xff1…...

SpringBoot整合接口管理工具Swagger

Swagger Swagger简介 Springboot整合swagger Swagger 常用注解 一、Swagger简介 ​ Swagger 是一系列 RESTful API 的工具&#xff0c;通过 Swagger 可以获得项目的⼀种交互式文档&#xff0c;客户端 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 请求映射到一个组件&#xff0c;其中 path 表示请求的 URL&#xff0c;component 表示对应的组件。 通过 const…...

JavaScript小记——事件

HTML 事件是发生在 HTML 元素上的事情。 当在 HTML 页面中使用 JavaScript 时&#xff0c; JavaScript 可以触发这些事件。 Html事件 HTML 事件可以是浏览器行为&#xff0c;也可以是用户行为。 以下是 HTML 事件的实例&#xff1a; HTML 页面完成加载HTML input 字段改变…...

Windows逆向安全(一)之基础知识(八)

if else嵌套 这次来研究if else嵌套在汇编中的表现形式&#xff0c;本次以获取三个数中最大的数这个函数为例子&#xff0c;分析if else的汇编形式 求三个数中的最大值 首先贴上代码&#xff1a; #include "stdafx.h"int result0; int getMax(int i,int j,int k)…...

PyCharm+PyQt5+pyinstaller打包labelImg.exe

0 开头 labelImg是一款标注软件&#xff0c;作为一个开源项目&#xff0c;它的源码可以在github上找到。官方仓库地址为&#xff1a; https://github.com/heartexlabs/labelImg 小白安装时的最新版本编译出来的界面长这样&#xff1a; 之前在小白的博客里&#xff0c;也教过…...

WaveTools鸣潮工具箱实战指南:从画质优化到抽卡策略的新视角

WaveTools鸣潮工具箱实战指南&#xff1a;从画质优化到抽卡策略的新视角 【免费下载链接】WaveTools &#x1f9f0;鸣潮工具箱 项目地址: https://gitcode.com/gh_mirrors/wa/WaveTools 当我在宿舍用老旧笔记本玩《鸣潮》时&#xff0c;画面卡顿得连技能都放不连贯&…...

提示工程延迟优化的终极技巧:这6个方法,让你无延迟

提示工程延迟优化终极指南&#xff1a;6个技巧让你的AI响应“飞”起来 1. 标题选项 《提示工程延迟优化终极指南&#xff1a;6个技巧让你的AI响应“飞”起来》《告别等待&#xff01;提示工程延迟优化的6个关键方法》《AI响应慢&#xff1f;这6个提示工程技巧帮你解决延迟痛点》…...

CasaOS应用商店太单调?试试这几个社区维护的源,青龙面板、迅雷都能一键装

CasaOS社区应用源全攻略&#xff1a;解锁青龙面板、迅雷等本土化神器 如果你已经厌倦了CasaOS官方应用商店里那些千篇一律的容器镜像&#xff0c;正为找不到迅雷下载、青龙面板这类中国特色应用而发愁&#xff0c;那么这篇文章就是为你准备的。作为一个长期折腾家庭服务器的玩家…...

保姆级教程:用迪文屏官方工具生成30x30点阵汉字库,搞定界面文本显示

嵌入式UI开发实战&#xff1a;迪文屏3030点阵汉字库生成全流程指南 在嵌入式设备的人机交互界面开发中&#xff0c;文本显示是最基础却最容易出问题的环节之一。许多开发者第一次使用迪文屏时&#xff0c;往往会被字库生成工具的参数设置难住——为什么明明生成了字库&#xf…...

Java大厂面试揭秘:从Spring Boot到Kubernetes的技术深挖

Java大厂面试揭秘&#xff1a;从Spring Boot到Kubernetes的技术深挖 场景背景 王大壮是一位初入职场的程序员&#xff0c;怀揣着对互联网大厂的向往&#xff0c;来到了一家知名互联网企业参加Java开发岗的面试。面试官老李以严肃的态度&#xff0c;针对核心技术栈进行了深挖式提…...

IDC行业专家交流纪要

Q&#xff1a;字节 2026 年 IDC 招标的总需求、国内需求、当前招标进度分别是怎样的&#xff1f;此次招标呈现出怎样的特点&#xff0c;背后又有哪些原因&#xff1f;A&#xff1a;字节跳动 2026 年 IDC 招标整体规划总需求约 1.8GW&#xff0c;剔除海外需求削减的部分后&#…...

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型 【免费下载链接】odoo Odoo. Open Source Apps To Grow Your Business. 项目地址: https://gitcode.com/GitHub_Trending/od/odoo 企业在合同管理过程中常面临效率低下、合规风险高、协作成本大等挑战。传统…...

告别OpenAI依赖:用智谱AI与轻量本地模型构建RAG评估实战

1. 为什么需要替代OpenAI的RAG评估方案 当我们在构建RAG&#xff08;检索增强生成&#xff09;系统时&#xff0c;评估环节至关重要。传统的Ragas框架默认使用OpenAI的GPT模型进行评估&#xff0c;但这会带来几个实际问题&#xff1a; 首先是访问稳定性问题。由于网络环境差异…...

熬夜赶论文效率低到哭?,有哪些真正值得体验的的降AIGC软件推荐?

毕业论文降AIGC率&#xff0c;优先选语义重构 AI痕迹清除 降重优化的工具&#xff0c;免费与付费结合最实用。下面按中文、英文、免费/付费分类推荐&#xff0c;附实测效果与适用场景。 一、中文论文降重工具&#xff08;最常用&#xff09; 1. 千笔AI&#xff08;综合全能首…...

Qwen3-Reranker-0.6B效果展示:长文档片段(32K)语义匹配能力实测

Qwen3-Reranker-0.6B效果展示&#xff1a;长文档片段&#xff08;32K&#xff09;语义匹配能力实测 1. 引言&#xff1a;当搜索遇到“大海捞针” 你有没有过这样的经历&#xff1f;面对一份几十页的PDF报告&#xff0c;或者一个包含数千条记录的数据库&#xff0c;想快速找到…...