一文搞定c++多线程

C++多线程详解(全网最全) 在C++学习过程中,要想“更上一层楼”的话,多线程编程是必不可少的一步,前面的文章多半是基础方面的内容,这节的话稍微有点拔高。所以说,我们在看这篇文章的时候,大家需要更多的思考是为什么这么做?这样做的好处是什么?以及多线程编程都可以应用在哪里?话不多说,跟着我一起认真探讨这块内容。传统的C++(C++11标准之前)中并没有引入线程这个概念,在C++11出来之前,如果我们想要在C++中实现多线程,需要借助操作系统平台提供的API,比如Linux的,或者windows下的。 阅读详情

一文搞定c++多线程

c++11引入了用于多线程操作的thread类,该库移植性更高,并且使得写多线程变得简洁了一些。

多线程头文件支持

为了支持多线程操作,c++11新标准引入了一些头文件来支持多线程编程:

  • <thread>:内部声明了 std::thread 类,用于创建多线程
  • <atomic>:内部声明std::atomic 和 std::atomic_flag两个类,可以利用这两个类实现原子类型的各种特性,并且声明了一些原子操作函数
  • <mutex>:提供了多种互斥操作,可以显式避免数据竞争,内部包含mutex类型、lock类型以及功能函数.
  • <condition_variable>:声明了与条件变量相关的类,包括 std::condition_variable 和 std::condition_variable_any
  • <future>:通过特殊的provider进行数据的异步访问,实现线程间的通信,主要用于支持异步访问。
多线程示例
简单多线程

一个简单的多线程:

#include <iostream>
#include <thread>
using namespace std;
void thread_test()
{
   
   
    std::cout << "I'm thread_test()\n";
}
int main()
{
   
   
    std::thread t1(thread_test);
    cout << "I'm main_thread\n";
    //do somtthing
    t1.join();
    return 0;
}

部分需要补充的点:

  • main函数构建了一个std::thread对象t1,构造的时候传递了一个函数参数,这个参数就是线程的入口函数,函数执行完了,整个线程也就执行完了,线程创建成功后,就会立即启动
  • 一旦线程开始运行, 就需要显式的决定是要等待它完成(join),或者分离它让它自行运行(detach)。注意:只需要在std::thread对象被销毁之前做出这个决定
  • 调用join(),主线程会一直阻塞着,直到子线程完成,join()函数的另一个任务是回收该线程中使用的资源,如果采用detach的话表示子线程和主线程分离,这样子线程将有操作系统管理,主线程结束后也thread对象被析构,但是该线程仍将继续执行至结束。
detach和join的区别

在任何一个时间点上,线程是可结合的(joinable),或者是分离的(detached)。一个可结合的线程能够被其他线程收回其资源和杀死;在被其他线程回收之前,它的存储器资源是不释放的。相反,一个分离的线程是不能被其他线程回收或杀死的,它的存储器资源在它终止时由系统自动释放。也就是说,分离状态还是可结合状态主要决定一个线程以怎样的方式终结。

当thread::join()函数被调用后,调用它的线程会被block,直到线程的执行被完成。基本上,这是一种可以用来知道一个线程已结束的机制。当thread::join()返回时,OS的执行的线程已经完成,C++线程对象可以被销毁。

当thread::detach()函数被调用后,执行的线程从线程对象中被分离,已不再被一个线程对象所表达–这是两个独立的事情。C++线程对象可以被销毁,同时OS执行的线程可以继续,也就是说主线程结束后该线程仍然可以继续运行,因此如果不关心一个线程的结束状态,那么也可以将一个线程设置为 detached 状态,从而让操作系统在该线程结束时来回收它所占的资源。

实际上,程序员应该在thread对象执行流程到析构函数前总是要么join,要么detach一个线程。当一个程序终止时(比如main返回),剩下的在后台的detached线程执行不会再等待;相反它们的执行会被挂起并且它们的本地线程对象会被销毁。通常情况下使用join即可。

否则会有问题:

#include <iostream>
#include <thread>  
#include <Windows.h>  
using namespace std;  
void test_thread()  
{
   
     
        cout << "Another thread  is working!\n" ;  
}    
int main()  
{
   
     
    thread task(test_thread);  
    cout << "Main thread is working!\n";  
    system("pause");  
}

这是一个很简单的多线程程序,但是并没有对task线程进行join或者detach,运行结果:

PS D:\vscode_c> ./test2
Main thread is working!
Another thread is working!
请按任意键继续. . .
terminate called without an active exception

出现这个情况的原因就是std::thread在main()结束的时候,被销毁了,解决办法就是对每一个进程都进行join或者detach(根据具体需求)。在代码上加入task.join(); 即可

join多线程

join函数会阻塞主流程,所以子线程都执行完成之后才继续执行主线程

#include <iostream>
#include <thread>  
#include <Windows.h>  
using namespace std;  
void thread1()  
{
   
     
    for (int i = 0; i < 5; i++)  
    {
   
     
        cout << "Thread 1 is working!\n" ;  
        Sleep(200);  
    }  
}  
void thread2()  
{
   
     
    for (int i = 0; i < 5; i++)  
    {
   
     
        cout << "Thread 2 is working!\n" ;  
        Sleep(100);  
    }  
}  
  
int main()  
{
   
     
    thread task01(thread1);  
    thread task02(thread2);
    task01.join();
    task02.join();
    for (int i = 0; i < 5; i++)  
    {
   
     
        cout << "Main thread is working!" << endl;  
        Sleep(200);  
    }
    system("pause");  
}

运行结果:

PS D:\vscode_c> ./test                
Thread 1 is working!
Thread 2 is working!
Thread 2 is working!
Thread 1 is working!
Thread 2 is working!
Thread 2 is working!
Thread 1 is working!
Thread 2 is working!
Thread 1 is working!
Thread 1 is working!
Main thread is working!
C++23 多线程详解(全网最全,代码均已实测) 本文全面详解C++23多线程特性,基于GCC 14.2与-std=c++23编译通过,经ThreadSanitizer验证无数据竞争。涵盖std::jthread、std::stop_token、std::latch/barrier/counting_semaphore、std::atomic::wait、std::print及std::move_only_function等新特性,修复旧版线程池死锁与资源泄漏问题。强调避免detach,推荐使用自动管理生命周期的jthread,并提供完整可运行示例,确保跨 阅读详情

相关推荐

C++怎么学?零基础也可以,一份完整学习路线图助你搞定!

提供一条清晰、系统且实践导向的C++学习路径。从基础语法、面向对象、泛型编程、异常处理,逐步深入STL、智能指针、并发编程等现代C++高级特性。无论是新手还是希望提升,通过系统学习与项目实践,助您将理论知识转化为实际解决问题的能力。

Lion_Long的博客 4027

基于STM32和K210的自动驾驶小车设计

自动驾驶技术正在迅速发展,成为了汽车行业和智能交通领域的热点之一。随着科技的发展,STM32和K210这两款芯片为自动驾驶小车提供了优秀的硬件支持。本文我们将学习如何使用STM32和K210打造一个简单的自动驾驶小车。提示:以下是本篇文章正文内容,下面案例可供参考通过这篇文章,掌握了如何使用STM32和K210构建一个简单的自动驾驶小车。通过了解基本的电路设计,并编写了STM32和K210的代码。通过这个例子,可以更好地理解如何在嵌入式系统中使用STM32和K210,以及如何实现自动驾驶小车的简单功能。

Kyle_Chan_zMH的博客 2220

Allegro PCB设计实战:5分钟搞定DDR信号线的Match Group等长规则设置

本文详细介绍了在Allegro PCB设计中,如何快速为DDR信号线设置Match Group等长规则。通过实战演练,解析了从理解相对传输延迟原理、在规则管理器中创建Match Group,到设置合理容差和利用动态绕线指示的全流程,帮助工程师在5分钟内高效完成高速信号时序约束,提升设计可靠性与效率。

gg901的博客 1055

RK平台MPP编解码实战:从源码编译到性能测试全解析

本文详细解析了在RK(瑞芯微)平台上进行MPP(Media Process Platform)多媒体编解码实战的全过程。从源码获取、交叉编译环境搭建、常见编译问题排查,到测试程序的修改调试与性能测试分析,提供了从零到一的完整指南。文章通过实测数据展示了MPP硬件编解码在嵌入式设备上的高性能与低功耗优势,帮助开发者快速掌握这一关键技术,应用于智能摄像头、视频会议终端等产品开发。

weixin_28273593的博客 545

Raid5损坏两块盘

  以下为浪潮Inspur NF5460M4型号服务器故障处理过程: 设备raid5组损坏两块硬,并raid组处理离线状态,情况如图:     由于硬盘数据比较重要,面对此情况不要慌我们尽量做到安全保守的保证数据尽可能完整,以下为处理方法,(遇raid5两块盘出现问题处理方法)   以下截图均为遇相同问题的解决图案,并非现场截图。 Ctrl+H 进WebBios界面,发现两...

chen_lipeng的博客 2万+

Java调用YOLOv26全解析:从ONNX模型部署到工业质检实战

本文分享了工业自动化领域使用Java调用YOLOv26进行零件缺陷检测的完整方案。通过YOLOv26s模型结合ONNX Runtime Java部署,误检率和漏检率显著降低(分别从12%降至2.1%,8%降至0.8%)。文章详细介绍了方案选型理由、环境配置避坑指南、ONNX模型导出步骤,以及Maven依赖配置(分CPU/GPU版本)。该方案直接在上位机Java环境中运行,避免了跨语言调用损耗,适合工业质检场景部署,提供了可复用的性能优化和多线程推理实现。

2601_94871597的博客 1108

K-BERT: Enabling Language Representation with Knowledge Graph 代码复现 直接运行

K-BERT: Enabling Language Representation with Knowledge Graph K-BERT K-BERT 代码复现

1074

大模型对齐的核心引擎:RLHF三阶段完整技术体系详解——从InstructGPT到ChatGPT与Claude 4.6的工程实践

RLHF从InstructGPT起步,经由ChatGPT、Claude系列的工程实践,已演变为现代大语言模型不可或缺的对齐基础设施。其三阶段流程——SFT构建基础能力基线,奖励模型将人类偏好编码为可微信号,PPO以KL约束驱动策略向偏好分布优化——构成了当代对齐技术的核心骨架。OpenAI的路线侧重于以海量人工标注和多目标奖励建模持续精细化RLHF流程,在规模与工程深度上持续推进;

nmdbbzcl的博客 1067

基于深度学习的CT图像肺结节分割与检测系统[完整代码数据分享]

基于深度学习的CT图像肺结节分割与检测系统[完整代码数据分享]

269

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

C# WinForm 基于DirectShow.dll编写的程序,可边预览边保存视频,音频和图片

基于微软的DirectShow.dll的二次开发1.自动识别连接的摄像头跟麦克风且可以对其进行选择(默认选中第一个)2.可录制wmv和avi两种格式的视频并且都带有音频,avi可以录制的分辨率和帧数进行选择,wmv默认进行了淸晰度优化如不喜欢可去除代码中有相关提示3.可在预览点开之后进行拍照,也可边录制视频边拍照4.添加了视频和音频的压缩功能(酌情使用)这次二次开发发现C#对DirectShow的相关信息太少,这次做完也不敢藏私共享出来,还望大家指正

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

上一篇: 深入探索网络IO模型
下一篇: 一文搞定c++多线程同步机制
coding丁
博客等级 码龄9年 383粉丝 147原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值