C++:线程(std::thread)

C++多线程:创建线程 C++中线程的创建一般是通过std::thread类实现的,具体的实现方式有以下几种: 1 使用函数名创建 void pcreat(int a) { cout << "start !" << a << endl; } int main() { thread p(pcreat,4); //如果函数无参则省略第二个参数,多参数直接加在后面即... 阅读详情

C++:线程(std::thread)

1.创建一个线程

  创建线程比较简单,使用std的thread实例化一个线程对象就创建完成了,示例:

复制代码

 1 #include <iostream>
 2 #include <thread>   //C++11才有,之前是pthread.h文件
 3 using namespace std;
 4 
 5 void t1()  //普通的函数,用来执行线程
 6 {
 7     for (int i = 0; i < 20; ++i)
 8     {
 9         cout << "t1111\n";
10     }
11 }
12 void t2()
13 {
14     for (int i = 0; i < 20; ++i)
15     {
16         cout << "t22222\n";
17     }
18 }
19 int main()
20 {
21     thread th1(t1);  //实例化一个线程对象th1,使用函数t1构造,然后该线程就开始执行了(t1())
22     thread th2(t2);
23 
24     cout << "here is main\n\n";
25 
26     return 0;
27 }

复制代码

  不过这个示例是有问题的,因为在创建了线程后线程开始执行,但是主线程main()并没有停止脚步,仍然继续执行然后退出,此时线程对象还是joinable的,线程仍然存在但指向它的线程对象已经销毁,所以会抛出异常。

  那么该如何保证子线程执行完了退出后再退出主线程呢?

2.thread::join()

  使用join接口可以解决上述问题,join的作用是让主线程等待直到该子线程执行结束,示例:

复制代码

#include <iostream>
#include <thread>
using namespace std;

void t1()
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t1111\n";
    }
}
void t2()
{
    for (int i = 0; i < 20; ++i)
    {
        cout << "t22222\n";
    }
}
int main()
{
    thread th1(t1);
    thread th2(t2);
    
    th1.join(); //等待th1执行完
    th2.join(); //等待th2执行完

    cout << "here is main\n\n";

    return 0;
}

复制代码

  此时就可以正常地执行子线程了,同时注意最后一个输出,说明了main是等待子线程结束才继续执行的

  需要注意的是线程对象执行了join后就不再joinable了,所以只能调用join一次。

3.thread::detach()

  (1.)中提到的问题,还可以使用detach来解决,detach是用来和线程对象分离的,这样线程可以独立地执行,不过这样由于没有thread对象指向该线程而失去了对它的控制,当对象析构时线程会继续在后台执行,但是当主程序退出时并不能保证线程能执行完。如果没有良好的控制机制或者这种后台线程比较重要,最好不用detach而应该使用join。

复制代码

int main()
{
    thread th1(t1);
    thread th2(t2);
    
    th1.detach();
    th2.detach();

    cout << "here is main\n\n";

    return 0;
}

复制代码

  由结果可见线程并没有执行完而退出:

4.mutex

  头文件是<mutex>,mutex是用来保证线程同步的,防止不同的线程同时操作同一个共享数据。

复制代码

int cnt = 20;
mutex m;
void t1()
{
    while (cnt > 0)
    {    
        m.lock();
        
        if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }

        m.unlock();
    }
}
void t2()
{
    while (cnt > 0)
    {
        m.lock();
        
        if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }

        m.unlock();
    }
}
int main()
{
    
    thread th1(t1);
    thread th2(t2);
    
    th1.join();
    th2.join();

    return 0;
}

复制代码

  运行结果,cnt是依次递减的,没有因为多线程而打乱次序:

  但是使用mutex是不安全的,当一个线程在解锁之前异常退出了,那么其它被阻塞的线程就无法继续下去。

5.std::lock_guard

  使用lock_guard则相对安全,它是基于作用域的,能够自解锁,当该对象创建时,它会像m.lock()一样获得互斥锁,当生命周期结束时,它会自动析构(unlock),不会因为某个线程异常退出而影响其他线程。示例:

复制代码

int cnt = 20;
mutex m;
void t1()
{
    while (cnt > 0)
    {    
        lock_guard<mutex> lockGuard(m);
        if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }
        
    }
}
void t2()
{
    while (cnt > 0)
    {
        lock_guard<mutex> lockGuard(m);
        if (cnt > 0)
        {
            --cnt;
            cout << cnt << endl;
        }
    
    }
}

复制代码

 

------------ 转载请注明出处 ------------

https://www.cnblogs.com/whlook/p/6573659.html

C++11 多线程支持之std::thread 从C++11开始,C++标准库已经支持了线程库了,其实在底层,仍旧使用的是平台相关的线程API 有了std::thread之后,我们就不用在不同的平台使用不同的API了,比如Unix平台使用pthread, windows平台使用WinSDK的CreateThread了,接口使用去掉了平台差异性,使得项目开发具有更好的移植性1. std::thread的使用方法A. 所需头文件#include < 阅读详情

相关推荐

C++线程库std::thread和std::async的用法详解

C++作为一门强大的系统编程语言,提供了多种并发编程工具,使得开发者可以充分利用多核处理器的性能。C++11标准引入了新的线程库,包括std::thread和std::async,为开发高效并发应用提供了强大支持。下面我将std::thread和std::async的用法及其原理做一个归纳总结,希望对大家有帮助。

程序猿老樊的博客 1773

在子线程中创建子线程及线程查看方法

小结:我们看到,son线程的退出,并没有影响到孙线程的运行,因为进程并未退出。 以上述方式一的形式查看线程:1)同一进程中的线程是平等的,没有父子之分。当然也包括所谓的主线程、在主线程中创建的线程、在所谓的子线程中创建的线程。线程既然是平等的,只要进程不退出,倘若son线程退出,我们看到不会影响到孙线程的运行。2)孙线程在子线程中创建,可以理解为,启动孙线程的顺序点是在此时,而并非在主线程中。也就是说,我们可以在任意我们需要创建一个平行任务的地方,创建一个子线程,而并非得在主线程中创建。3)线程函数,其实,

modi000的博客 3070

使用std :: thread将多个线程的数组组合在一起使用std :: thread

#include <iostream> #include <vector> #include <thread> #include <mutex> #include <cassert> #include "boost/multi_array.hpp" std::vector<float> Array; std::mutex Array_mutex; void Summation(int sample_size) {

M2嵌入式 1498

C++11 多线程(std::thread)详解

本文介绍了C++11标准库中的std::thread多线程编程基础。

jcShan709的博客 15万+

std::thread初始化(1)--普通函数

#include <iostream> #include <utility> #include <thread> #include <chrono> void f1(int n) { std::cout << "function f1\n"; ++n; } void f2(int& n) { std::cout << "function

鸟哥的博客 1021

C++11 std::thread创建线程的几种写法

文章目录**1 简介****2 使用说明**1、通过函数指针创建2、通过函数对象创建3、通过lamda表达式创建4、通过成员函数创建 1 简介 本文主要介绍标准C++中 thread的创建线程的几种方式。 使用时需要加头文件:#include <thread> 位于std命名空间中,是跨平台的线程操作。 2 使用说明 1、通过函数指针创建 一般来说,像linux下pthread_create创建线程时,都会先写一个**含有一个参数(LPVOID lpParam)**的全局函数,用于通过函数指针创

二进制君 2万+

CPP多线程1:C++11的std::thread

C++11引入的std::thread是对C语言pthread的改进,提供了更便捷的多线程编程方式。文章介绍了std::thread的常用成员函数,并通过四个示例演示了其基本使用、参数传递(包括引用参数)、以及类成员函数的调用方式。关键点包括:线程的异步执行特性、使用std::ref传递引用参数、类成员函数的调用语法。最后强调了注意事项:线程在定义时即开始执行,必须调用join或detach以避免异常,强制终止线程可能导致资源泄漏。这些内容为C++多线程编程提供了基础指导。

weixin_51878399的博客 826

C++ std::thread多线程编程实践指南

在多线程编程中,共享数据的安全访问是一个至关重要的问题。当多个线程试图同时读写同一数据时,就会出现竞争条件,可能会导致数据不一致。为了解决这个问题,C++标准库提供了互斥量(mutex),它是一种同步工具,用于保护共享资源的访问。互斥量可以用来保证一段代码在同一时刻只被一个线程执行。它通常用于以下几个目的:防止多个线程同时访问同一个资源(临界区)。保证共享资源的一致性。防止因并发执行而产生的竞争条件。标准库中的std::mutex。

weixin_31569663的博客 1106

C++ std::thread线程类 相关问题、函数总结

特性说明构造即启动线程在创建时立即开始执行移动语义线程所有权可转移,不可复制必须在线程析构前调用,否则程序终止参数传递默认值传递,引用需用std::ref,大对象用std::move异常隔离线程内异常不会传播到主线程RAII模式推荐使用包装类管理线程生命周期正确使用始终管理线程生命周期(join/detach)谨慎处理共享数据(使用同步原语)避免线程间悬垂引用考虑性能影响和线程创建开销优先使用高级抽象(如std::async)简化代码。

zxf347085420的博客 1024

从SAS接口到InfiniBand:一张图看懂数据中心硬件‘黑话’(SFF-8643/8644、QSFP112、NDR/HDR/EDR)

本文深入解析数据中心硬件术语,从SAS接口标准(SFF-8643/8644)到速率标识(NDR/HDR/EDR),帮助工程师快速理解关键性能指标。特别对比了PCIe卡规格(HHHL/FHHL)和光模块选择(QSFP112/OSFP),并探讨InfiniBand在高性能网络中的优势,为硬件选型提供实用指南。

weixin_32103009的博客 432

把MinerU集成到Dify

本文介绍了如何将本地部署的MinerU与Dify平台进行集成。首先需要确保Dify和MinerU在Docker环境中正常运行,并通过配置虚拟网络实现互联。然后详细说明了在Dify平台安装MinerU插件的步骤,包括从插件市场搜索安装、配置连接参数等关键操作。特别强调了要等待MinerU容器完全启动(healthy状态)后再进行Dify配置,否则会出现连接错误。通过简单的URL指向和API密钥设置,用户即可实现Dify平台与本地MinerU算力网络的对接,为后续的AI应用开发提供基础支持。

lyxerlau的博客 314

【C++11】线程创建于管理(std::thread)详解

本文详细阐述了如何使用std::thread构造函数创建线程,包括传递函数、函数指针、成员函数、lambda表达式等作为线程的执行体。同时,介绍了线程管理的核心方法,包括join()用于等待线程结束,detach()用于分离线程使其独立运行,以及joinable()用于检查线程是否可被join或detach。

byte轻骑兵的技术小窝 4559

2025最新OSM中国矢量数据保姆级下载指南(附百度网盘链接)

本文提供2025年OSM中国矢量数据的保姆级下载与使用指南。详细介绍了通过Geofabrik镜像站、QGIS插件及第三方平台获取数据的多种途径,重点解析了Shapefile格式数据的结构、WGS84坐标系特性,并指导进行格式转换与基础GIS应用,帮助用户高效合规地获取并利用这份开放地理数据资源。

weixin_29228781的博客 884

c++ 多线程std::thread总结

c++多线程

weixin_45626706的博客 2482

ZYNQ裸机LWIP双网口实现

文章目录前言一、LWIP双网口二、使用步骤1.部分说明2.部分代码总结 前言 一、LWIP双网口 由于项目需要多通讯口,查阅资料发现lwip支持多网口操作。于是,就开搞了。 二、使用步骤 1.部分说明 利用xemac_add函数在网卡链表中添加一个网卡,即使用netif块重复xemac_add操作。 先用轮询的方式实现双网口,后期修改为中断模式 2.部分代码 导入官方例程LWip echo server, 修改main函数,增加一个netif块 #if LWIP_IPV6==0 #if L..

weixin_35865280的博客 1万+

Unity 面试篇|(四)Unity性能优化篇 【全面总结 | 持续更新】

Unity中,CPU准备好需要绘制的元素,对底层图形程序接口进行调用的过程,每次引擎准备数据并通知GPU的过程称为一次Draw Call。DrawCall越高对显卡的消耗就越大。降低DrawCall的方法:动态合批静态合批降低shader的等级特性场景优化策略——遮挡技术。rectMask2D替代Mask。

游戏开发小Y的博客 13万+

【C++ 包裹类 std::thread】探索C++11 std::thread:如何使用它来创建、销毁和管理线程

探索C++11 std::thread:如何使用它来创建、销毁和管理线程

探索C++编程的奥秘,分享深入的技术见解和实践,旨在激发读者创造力与解决问题的思维。 2944

从点击图标到Activity亮屏:AMS、Zygote、ActivityThread的Binder协作之旅

Launcher通过Context调用 startActivity(),最终会通过 Activity.startActivity() 传递到 ActivityManager.getService(),获取AMS的Binder代理对象(IActivityManager)。这里的 attach() 方法通过Binder调用AMS的 attachApplication(),将新进程的 IApplicationThread 代理对象传递给AMS。这一步的Binder通信,是整个启动流程的关键转折点,值得细细品味。

大模型大数据攻城狮的专栏 1071

C++ std::thread 线程创建和启动

使用函数指针或成员函数指针:如果线程函数是一个全局函数、静态成员函数或非静态成员函数,可以直接将函数指针或成员函数指针作为参数传递给 std::thread 构造函数。使用 std::mutex、std::condition_variable 或 std::atomic 等同步机制,可以自定义线程状态的检查和控制。std::thread 是C++11标准引入的一个轻量级线程库,它提供了创建和管理线程的能力,方便用户创建新的线程,并执行指定的函数。定义线程函数:首先需要定义一个函数,作为线程的入口点。

GodJhin的博客 2031

QGis二次开发 —— 1.1、ubuntu24.04下搭建QGis3.40.12二次开发环境(附:全部问题解决方法)

QGis二次开发 —— 1.1、ubuntu24.02下搭建QGis3.40.12二次开发环境(附:全部问题解决方法)

252

RTT Studio和Cubemx联合开发

1. RTT studio创建工程 创建工程 ## 创建完成以后的目录结构 2. 配置CubuMx 双击cubumx的图标打开CubeMx 配置时钟 生成代码 构建后的代码结构 编译代码满屏错误:不要慌 3. 新增脚本 新建scons脚本文件 SConscript 脚本内容如下 import os from building import * cwd = GetCurrentDir() src = Glob('*.c') # add cubemx drivers src = Split('''

Car12 1565

C++11多线程std::thread

在C++11之前,多线程我们一般使用ptread库。C++11提供了一个很好用于线程操作的标准库std::thread,编码时需引入头文件#include,std::thread在linux下调用的是原有的pthread api实现线程操作,因此编译时需加上lpthread库。 1. 默认构造函数 thread() noexcept: 默认构造函数,创建一个空的 std::thread 执行对象。...

Lyu-ming 栏目 1757

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

C++多线程:std::thread与std::async对比(十一)

std::thread是C++11中提供的创建线程的一个手段,它是在<thread>头文件中,它的返回值是一个线程主体对象,主要提供下面几个函数join:调用该指令所在的线程阻塞,等待被调用线程的执行完毕detach:调用该指令所在的线程与被调用线程分离,无须管理被调用线程的生死joinable:判断线程是否可以join和detach,因为这两个方法只能调用一次native_handle:获得句柄,应该是线程执行的入口函数get_id:获取线程id。

weixin_43808717的博客 1546

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C++ 中 std::jthread 与 std::thread 的区别:C++20 线程管理的进化

不是的颠覆性替代,而是在其基础上的重要改进。自动 join 解决安全问题jthread在析构时自动 join,从根本上消除了thread析构时因忘记 join/detach 导致程序崩溃的风险。这使得 C++ 线程管理第一次真正实现了 RAII 友好的设计。stop_token 实现优雅取消jthread内置的 stop_token 机制提供了标准化的协作式线程取消方案。被取消的线程可以优雅地完成清理工作,而不是被强制终止。这比使用原子 bool 标志或条件变量更加标准化和可靠。完全向下兼容。

✨ 欢迎来到【Seal ^_^ 的优快云博客】!✨ 453

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

上一篇: 锁 和 CopyOnWrite的实现
下一篇: C++ 11和C++98相比有哪些新特性
Poo_Chai
博客等级 码龄9年 178粉丝 117原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值