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

C++一文讲透thread中的detach和join的差别

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

文章目录

  • 前言
  • 一、thread详解
  • 二、线程何时运行
  • 三、线程启动方式
    • 1.join
    • 2.detach
  • 总结


前言

无论哪种语言线程在绝大多数项目中都是会用到的,C++也一样,C++包装了一个std::thread类可以简化程序员的编程,但在使用过程中也要注意区分用法,否则可能适得其反。

今天要讨论的就是单纯的thread的join(等待)和detach(分离)两种情景,让不懂得人看完之后茅塞顿开。


一、thread详解

C++标准库成员,是对线程的包装类,在thread头文件里面,使用方式是std::thread。创建线程本身就是通过创建一个thread类对象然后和系统线程完成绑定(映射),这样可以通过操作thread类对象来管理创建的系统线程,系统线程本身行为受到内核调度机制影响。

示例代码:

#include <iostream>
#include <thread>// 线程函数
void threadFunction() {std::cout << "Thread function is running" << std::endl;
}int main() {// 创建线程并启动std::thread t(threadFunction);// 等待线程完成t.join();std::cout << "Main thread is running" << std::endl;return 0;
}

注意:这个地方如果不使用t.join()可能导致main线程早于子线程结束,引发terminate!

二、线程何时运行

这个问题一定要说清楚才行,我以前用java的时候线程有一个start()可以决定什么时候启动线程,C++则不是这样,C++没有一个明确方法决定线程何时运行,只需要满足创建并等待(一般时间很短,取决于实际情况),直到线程获取了资源之后就会自动运行,而不需要显式调用方法。且无论是以join还是detach方式启动的线程都受到内核的调度。

三、线程启动方式

1.join

主线程(创建子线程的那个线程)等待子线程执行完毕才进行下一步,适合那种需要立刻得到结果的场景。创建方式很简单,你只需要先创建线程然后在合适的时候调用t.join()等待结束即可。

示例代码:

#include <iostream>
#include <thread>int main() {std::thread t([]{std::cout << "Lambda function is running" << std::endl;});t.join();std::cout << "Main thread is running" << std::endl;return 0;
}

当调用t.join()方法时主线程的等待,直到t线程结束主线程才会继续运行,程序结束。如果子线程里面有死锁主线程就会一直等待,永无休止。

2.detach

在C++中,std::thread提供了一个detach方法,可以将线程从其控制对象中分离。分离的线程会在后台独立运行,直到完成。此方法常用于不需要同步或获取线程结果的情况。不过,在使用detach时需要小心,因为主线程不能再控制或管理该分离的线程,这可能会导致资源管理和程序结束时的问题。

另外,detach之后的变量不能重新join。

示例代码:

#include <iostream>
#include <thread>
#include <chrono>void worker() {std::this_thread::sleep_for(std::chrono::seconds(2));std::cout << "Worker thread finished\n";
}int main() {std::thread t(worker);// 分离线程t.detach();std::cout << "Main thread finished\n";// 此处主线程可能已经结束,而分离的线程仍在运行std::this_thread::sleep_for(std::chrono::seconds(3));  // 确保主线程不会立即退出return 0;
}

创建的子线程很快就会结束,所以主线程3秒的休眠足够了,如果子线程超过3秒就会导致主线程早于子线程结束,程序terminate。

terminate called without an active exceptionProcess finished with exit code 3

所以,还是要面对一个问题,detach后的线程怎么管理?我并不能时时刻刻知道线程的状态,如果主线程结束了子线程没结束怎么办?方法还是有的,那就是增加标志位(同步需要atomic或锁),如果我想一个线程结束只需要修改标志位。比如下面的代码:

#include <iostream>
#include <thread>
#include <atomic>
#include <chrono>std::atomic<bool> keepRunning(true); // 原子布尔变量,用于控制线程执行void threadFunction() {while (keepRunning) {std::cout << "Thread is running..." << std::endl;std::this_thread::sleep_for(std::chrono::seconds(1));}std::cout << "Thread stopped." << std::endl;
}int main() {std::thread t(threadFunction);// 主线程等待一段时间后停止子线程std::this_thread::sleep_for(std::chrono::seconds(5));keepRunning = false; // 设置标志位,通知线程停止t.join(); // 等待线程结束std::cout << "Main thread is running" << std::endl;return 0;
}

还可以借助boost库的方法来打断线程。例如:

#include <iostream>
#include <boost/thread.hpp>void threadFunction() {try {while (true) {// 执行一些工作boost::this_thread::interruption_point();}} catch (boost::thread_interrupted&) {std::cout << "Thread interrupted." << std::endl;}
}int main() {boost::thread t(threadFunction);// 主线程等待一段时间后中断子线程boost::this_thread::sleep_for(boost::chrono::seconds(5));t.interrupt(); // 中断线程t.join(); // 等待线程结束std::cout << "Main thread is running" << std::endl;return 0;
}

切记,不要随意中断线程,防止资源泄露!不管是标志位、条件判断还是boost库都必须考虑资源回收的问题,否则如果子线程里面使用了自由存储将永远无法得到回收。


总结

不管哪种方式启动的线程都要保证资源的回收,特别是当心主线程早于子线程结束的情况。还有一种容易让人疏忽的情况:如果你在一个函数里创建了thread对象,你没有join或detach,如果在函数return前线程没被回收就会导致terminate。比如,下面的代码:

void test(){
}void thread_join_detach(){std::thread t(test);
//    t.detach();
//    t.join();
}int main() {thread_join_detach();return 0;
}

上面的代码thread_join_detach函数返回会回收t对象,如果线程t还没结束就会terminate。解决方法有很多,比较简单的就是在函数return之前调用join或detach,还有就是把t提升作用域,比如全局变量。

相关文章:

C++一文讲透thread中的detach和join的差别

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、thread详解二、线程何时运行三、线程启动方式1.join2.detach 总结 前言 无论哪种语言线程在绝大多数项目中都是会用到的&#xff0c;C也一样&#xff0c;C…...

当Windows台式电脑或笔记本电脑随机关机时,请先从这8个方面检查

序言 你的Windows笔记本电脑或PC是否意外关闭?笔记本电脑电池故障、电源线松动、过热、电源设置错误、驱动程序过时或电脑组件故障等问题都可能是罪魁祸首。如果你对这个问题感到沮丧,试试这些解决方案。 进行一些初步检查 与从电池中获取电力的笔记本电脑不同,台式电脑依…...

【凤凰房产-注册安全分析报告-缺少轨迹的滑动条】

前言 由于网站注册入口容易被黑客攻击&#xff0c;存在如下安全问题&#xff1a; 1. 暴力破解密码&#xff0c;造成用户信息泄露 2. 短信盗刷的安全问题&#xff0c;影响业务及导致用户投诉 3. 带来经济损失&#xff0c;尤其是后付费客户&#xff0c;风险巨大&#xff0c;造…...

【建议收藏】逻辑回归面试题,机器学习干货、重点。

. . . . . . . . . . .纯 干 货 . . . . . . . . . . . .今天是机器学习面试题&#xff0c;16大块的内容&#xff0c;124个问题总结的第二期&#xff1a;逻辑回归面试题。 逻辑回归是一种用于解决分类问题的统计学习方法&#xff0c;尤其在二分类…...

C++使用教程

目录 一、软件使用 二、C基础规则补充 关键字 整型取值范围 浮点型取值范围 字符型使用规则 字符串型使用规则 布尔类型 常用的转义移字符 三、数组、函数、指针、结构体补充 1.数组 2.函数 声明&#xff1a; 分文件编写&#xff1a; 值传递&#xff1a; 3.指…...

k8s volcano + deepspeed多机训练 + RDMA ROCE+ 用户权限安全方案【建议收藏】

前提&#xff1a;nvidia、cuda、nvidia-fabricmanager等相关的组件已经在宿主机正确安装&#xff0c;如果没有安装可以参考我之前发的文章GPU A800 A100系列NVIDIA环境和PyTorch2.0基础环境配置【建议收藏】_a800多卡运行环境配置-CSDN博客文章浏览阅读1.1k次&#xff0c;点赞8…...

设计模式(七)创建者模式之建造者模式

这里写目录标题 概述需求需求类图BikeBuilderMobikeBuilderOfoBuilderDirectorClientClient优缺点使用场景 模式扩展ComputerClient创建者模式对比工厂方法模式VS建造者模式抽象工厂模式VS建造者模式 总结 概述 建造者模式又叫生成器模式&#xff0c;是一种对象构建模式。它可…...

# class中的__call__方法解析

class中的__call__方法解析 文章目录 class中的__call__方法解析1. 为什么要有call&#xff0c;什么情况下用call&#xff1f;1.1 为什么要有 __call__ 方法1.2 没有 __call__ 方法是否可以1.3 使用 __call__ 方法的典型场景1.3.1 示例1&#xff1a;简单函数对象1.3.2 示例2&am…...

React逻辑复用的方式都有哪些

在日常开发中&#xff0c;能够优雅的复用组件和逻辑&#xff0c;是优秀开发者的职责。在react中&#xff0c;复用逻辑的方式有很多&#xff0c;可以适用于不同的业务场景。今天说三个比较有代表性的&#xff0c;Render Props、HOC、Hooks Render Props 创建一个接受函数作为其…...

【LinuxC语言】线程重入

文章目录 前言线程重入是什么线程重入实现示例代码总结前言 在并发编程中,我们经常需要处理多个线程同时访问和修改共享资源的问题。这可能会导致数据竞争和状态不一致,从而使程序的行为变得不可预测。为了解决这个问题,我们引入了一种称为“线程重入”的机制。线程重入,或…...

【Streamlit学习笔记】Streamlit-ECharts箱型图添加均值和最值label

Streamlit-ECharts Streamlit-ECharts是一个Streamlit组件&#xff0c;用于在Python应用程序中展示ECharts图表。ECharts是一个由百度开发的JavaScript数据可视化库Apache ECharts 安装模块库 pip install streamlitpip install streamlit-echarts绘制箱型图展示 在基础箱型…...

Docker镜像仓库:存储与分发Docker镜像的中央仓库

探索Docker镜像仓库&#xff1a;存储与分发Docker镜像的中央仓库 如果你是Docker的新手&#xff0c;或者已经在使用Docker但还不太了解Docker镜像仓库&#xff0c;那么这篇博客将是你的最佳指南。我们将从基础概念开始&#xff0c;逐步深入&#xff0c;帮助你全面掌握Docker注…...

FreeRTOS必考面试题及参考答案

什么是RTOS?FreeRTOS是什么?它主要应用于哪些领域? RTOS,即实时操作系统(Real-Time Operating System),是一种专门为实时应用程序设计的操作系统,它强调的是对外部事件的快速响应和可预测性。实时系统通常要求在严格的时限内完成关键任务,因此RTOS具备优先级调度、确…...

面试题2:从浏览器输入一个URL,到最终展示前端页面这一过程,会发生什么?

这是一个高频的面试题目。 题目答案是开放性的&#xff0c;一般以后端开发的角度回答。 当地址栏输入一个 URL 后&#xff1a; 一、首先会进行 DNS 域名解析 DNS 域名解析&#xff1a;网络上的设备都是通过 IP 地址&#xff0c;作为身份标识的。但是由于点分十进制的 IP 地址 …...

<Rust><iced><resvg>基于rust使用iced构建GUI实例:使用resvg库实现svg转png

前言 本文是使用rust库resvg来将svg图片转为png图片。 环境配置 系统&#xff1a;windows 平台&#xff1a;visual studio code 语言&#xff1a;rust 库&#xff1a;resvg 代码分析 resvg是一个基于rust的svg渲染库&#xff0c;其官方地址&#xff1a; An SVG rendering li…...

面试突击:Java 中的泛型

本文已收录于&#xff1a;https://github.com/danmuking/all-in-one&#xff08;持续更新&#xff09; 前言 哈喽&#xff0c;大家好&#xff0c;我是 DanMu。今天想和大家聊聊 Java 中的泛型。 什么是泛型&#xff1f; Java 泛型&#xff08;Generics&#xff09; 是 JDK 5…...

3_2、MFC常用控件用法:组合框、滚动条和图片控件

MFC控件用法 1、组合框1.1 简介1.2 创建CComboBox类的主要成员函数 1.3 实例 2、滚动条控件2.1 简介2.2 创建CScrollBar类的主要成员函数 2.3 实例 3、图片控件3.1 简介3.2 创建图片控件静态加载图片图片控件动态加载图片 1、组合框 1.1 简介 组合框其实就是把一个编辑框和一…...

如何使用gprof对程序进行性能分析

如何使用gprof对程序进行性能分析 目录 1 gprof概述 2 gprof原理简述 3 gprof使用 3.1 gprof使用简述 3.2 gprof使用示例 4 小结 1 gprof概述 gprof 是 一个 GNU 的程序性能分析工具&#xff0c;可以用于分析C\C程序的执行性能。gprof工具可以统计出各个函数的调用次数、执…...

四川汇聚荣科技有限公司靠谱吗?

在如今这个信息爆炸的时代&#xff0c;了解一家公司是否靠谱对于消费者和合作伙伴来说至关重要。四川汇聚荣科技有限公司作为一家位于中国西部地区的企业&#xff0c;自然也受到了人们的关注。那么&#xff0c;这家公司究竟如何呢?接下来&#xff0c;我们将从多个角度进行深入…...

可灵王炸更新,图生视频、视频续写,最长可达3分钟!Runway 不香了 ...

现在视频大模型有多卷&#xff1f; Runway 刚在6月17号 发布Gen3 &#xff0c;坐上王座没几天&#xff1b; 可灵就在6月21日中午&#xff0c;重新夺回了王座&#xff01;发布了图生视频功能&#xff0c;视频续写功能&#xff01; 一张图概括&#xff1a; 二师兄和团队老师第一…...

oracle中使用临时表GLOBAL TEMPORARY TABLE

需要在存储过程中返回一个临时结果集&#xff0c;这个结果集又是多个语句通过循环查询出来的&#xff0c;这时候就想到了将结果插入到临时表中&#xff0c;然后返回临时表的数据的思路&#xff0c;于是有了以下操作&#xff1a; 1.创建临时表 -- Create table create global …...

Gradio入门—快速开始

目录 安装构建您的第一个演示分享您的演示核心 Gradio 课程聊天机器人gr.ChatInterface自定义演示gr.BlocksGradio Python 和 JavaScript 生态系统 Gradio 是一个开源 Python 软件包&#xff0c;可让您快速为机器学习模型、API 或任何任意 Python 函数构建演示或 Web 应用程序。…...

AOP应用之系统操作日志

本文演示下如何使用AOP&#xff0c;去实现系统操作日志功能。 实现步骤 引入AOP包 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-aop</artifactId><version>2.6.6</version></de…...

海外云手机自动化管理,高效省力解决方案

不论是企业还是个人&#xff0c;对于海外社媒的营销都是需要自动化管理的&#xff0c;因为自动化管理不仅省时省力&#xff0c;而且还节约成本&#xff1b; 海外云手机的自动化管理意味着什么&#xff1f;那就是企业无需再投入大量的人力和时间去逐一操作和监控每一台设备。 通…...

后仿真中的 《specify/endspecify block》之(5)使用specify进行时序仿真

前面我们学习了specify...endspecify 具体是什么东西。今天,我们使用specify block 中定义的延时,来进行一次仿真。看看到底是背后如何运转的呢。 一 基本例子 一个用 specify 指定延迟的与门逻辑描述如下: module and_gate(output Z,input A, B);assign Z = A & …...

win10/11磁盘管理

win10/11磁盘管理 合并磁盘分区的前提是你的两个磁盘区域是相邻的&#xff0c;比如如下&#xff1a; 如果需要吧这个磁盘进行分解&#xff0c;你可以选择压缩一部分磁盘或者是直接删除卷 我这里的话&#xff0c;因为压缩出来的卷和C盘好像是不相邻的&#xff08;我之前做过&…...

【昇思初学入门】第四天打卡

数据变换Transforms 心得体会 MindSpore提供了丰富的数据变换工具&#xff0c;针对图像数据可以使用如Rescale、Normalize和HWC2CHW等&#xff0c;且使用Compose类允许我们定义一个变换序列&#xff0c;并将它们作为一个整体应用到数据上。 composed transforms.Compose([v…...

禁用/屏蔽 Chrome 默认快捷键

Chrome 有一些内置的快捷键&#xff0c;但是它并没有像其他软件一样提供管理快捷键的界面。在某些时候&#xff0c;当我们因为个人需求希望禁用 Chrome 某些快捷键时&#xff0c;又无从下手。 好在有开发者开发了 Chrome 插件&#xff0c;可以禁用 Chrome 快捷键的插件&#x…...

移动端+PC端应用模式的智慧城管综合执法办案平台源码,案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析

城市管理综合执法管理平台实现执法办案、业务全流程在线办理&#xff0c;依托移动端PC端的“两端”应用模式&#xff0c;保障能够通过信息化手段进行日常的执法办案工作&#xff0c;强化执法监督功能。提供了案件在线办理、当事人信用管理、文书电子送达、沿街店铺分析等功能&a…...

AI音乐大模型时代:版权归属与创意产业的新生长点

AI在创造还是毁掉音乐&#xff1f; 简介&#xff1a;最近一个月&#xff0c;轮番上线的音乐大模型&#xff0c;一举将素人生产音乐的门槛降到了最低&#xff0c;并掀起了音乐圈会不会被AI彻底颠覆的讨论。短暂的兴奋后&#xff0c;AI产品的版权归属于谁&#xff0c;创意产业要…...

长沙的企业网站建设/关键词怎么选择技巧

逻辑简单&#xff0c;直接上代码。 #define _CRT_SECURE_NO_WARNINGS 1 //1.能够被4整除&#xff0c;但是不能被100整除的年份是闰年; //2.能够被400整除的年份是闰年#include<stdio.h> void leap_year_judge(int year)//判断闰年函数 {if ((year % 4 0 && yea…...

外贸网站模板免费下载/徐汇网站建设

解 决 无 法 修 改 my .ini 文 件 的 问 题 my. i ni —— 》 右 键 “ 属 性 ” —— 》 “ 安 全 ” —— 》 点 击 “ 编 辑 ” —— 》 选 择 你 现 在 登录的账号 —— 》 修 改 你 的 操 作 权 限 &#xff0c;其 中 包 括 &#xff1a;完 全 控 制 &#xff0c;修 改 &a…...

公司制作网站费用怎么做分录/如何做网页制作

概述 本文主要介绍下平常可能会使用到的命令&#xff1a;jps、jinfo、jmap、jstat、jstack jps jps主要是查看Java进程号&#xff0c;有个Java进程号后面的命令也才能发挥作用。 jps -help可以列出jps支持的参数&#xff0c;大家可以试一下 jinfo jinfo后面跟jps打出来的…...

动态网站建设第05章在线测试/武汉今日头条最新消息

简介 序列化是指将对象实例的状态存储到存储媒体的过程。在此过程中&#xff0c;先将对象的公共字段和私有字段以及类的名称&#xff08;包括类所在的程序集&#xff09;转换为字节流&#xff0c;然后再把字节流写入数据流。在随后对对象进行反序列化时&#xff0c;将创建出与原…...

无锡网站公司哪家好/深圳网络推广seo软件

二、桥接拦截器 BridgeInterceptor&#xff0c;连接应用程序和服务器的桥梁&#xff0c;我们发出的请求将会经过它的处理才能发给服务器&#xff0c;比如设置请求内容长度&#xff0c;编码&#xff0c;gzip压缩&#xff0c;cookie等&#xff0c;获取响应后保存Cookie等操作。这…...

南昌市网络开发公司/seo入门培训班

数据采集高并发框架同时&#xff0c; Cascading框架开发背后的企业面貌&#xff0c;已经在第一轮风险投资中获得了400万美元的投资。 该公司由Cascading的作者Chris Wensel于2008年创立&#xff0c;是第一批成立初创公司的公司&#xff0c;旨在应对开发大数据应用程序的复杂性。…...