std::thread::join()的使用

线程启动后,若想等待该线程结束,可以调用join()方法;

std::thread thisThread(function_ptr); // 做一些其他的事情 th.join();

下面看个例子:

以下代码逻辑如下:

  1. 先启动10个线程,线程都开始运行;
  2. 等待10个线程结束;
  3. 所有线程join()完成后,主线程就会继续运行;
#include #include #include class WorkerThread {public:  // 线程处理函数    void operator()() {        std::cout << "Worker Thread " << std::this_thread::get_id()                  << " is Executing" << std::endl;    }};int main() {    // 创建10个线程    std::vector<:thread> threadList;    for (int i = 0; i < 10; i++) {        threadList.push_back(std::thread(WorkerThread()));    }        // 等待所有线程都结束    // 对于每个线程调用其join()函数    std::cout << "wait for all the worker thread to finish" << std::endl;    std::for_each(threadList.begin(), threadList.end(),                  std::mem_fn(&std::thread::join));    std::cout << "Exiting from Main Thread" << std::endl;    return 0;}

执行结果如下

调用join()函数执行结果

std::thread::detach()的使用

Detached线程常被用于守护/后台线程。调用线程的detach()方法可以detach一个线程。

std::thread thisThread(function_ptr); th.join();// 做一些其他的事情

调用detach()方法后,被detach的线程将不再关联执行线程;

下面看个例子

以下代码逻辑为:

  1. 先创建一个线程,该线程执行函数里循环打印3次内容;
  2. detach该线程;
  3. 主线程循环打印15次内容;
#include #include #include class WorkerThread {public:    void operator()() {        for(int i = 0; i < 3; i++) {            printf("Worker Thread is Executing, Index %d", i);        }    }};int main() {    // 创建一个线程    auto detachThread = std::thread(WorkerThread());    // detach该线程    detachThread.detach();    // 继续主线程的一些事情,不受Worker线程影响    for(int i = 0; i < 20; i++) {        printf("Main Thread is Executing, Index %d", i);    }    std::cout << "Main Thread Enter Wait Status." << std::endl;    while(1) {        std::this_thread::sleep_for(std::chrono::milliseconds(3 * 1000));    }    return 0;}

结果如下:

detached的线程的执行结果

从上面可以看出:

  1. detached的线程不阻塞当前执行;
  2. detach的线程在后台运行;

调用join()和detach()需要注意的地方

  • 不要在没有关联执行线程的std::thread对象上调用join()和detach()函数

一个关联了执行线程的std::thread对象,其可以调用join()/detach()函数,调用过以后,该std::thread对象将不再关联任何执行线程,再次调用,则会终止程序。

// 创建一个线程对象auto joinThread = std::thread(WorkerThread());// join该线程joinThread.join();// 此处如果再次join,会引起程序崩溃// joinThread.join();

如何防止该类种异常发生呢?

  1. 自己记着有没有调用过;
  2. 调用std::thread的joinable()函数判断是否可以join/detach,如果返回true,则可以调用join()或detach()函数;
    // 创建一个线程对象    auto joinThread = std::thread(WorkerThread());    // join该线程    joinThread.join();    // 此处如果再次join,会引起程序崩溃    // joinThread.join();    if(joinThread.joinable()) {        joinThread.join();    }
  • 不要忘记在关联了执行线程的std::thread对象上调用join()和detach()函数

如果一个std::thread对象既没有调用join(),也没有调用detach()的话,则当std::thread析构的时候会引发程序崩溃。

示例程序:

#include #include #include class WorkerThread {public:    void operator()() {        for(int i = 0; i < 3; i++) {            printf("Worker Thread is Executing, Index %d", i);        }    }};int main() {    // 创建一个线程对象    auto joinThread = std::thread(WorkerThread());    // 此处如果不join该线程, 线程退出,joinThread对象析构会导致程序崩溃    // joinThread.join();    printf("Exist Main Thread");    return 0;}

执行如下:

没有调用join/detach引发的异常

可用的解决方案:

可以用自定义类包裹,在自定义类析构函数中detach()线程对象,代码如下:

#include #include #include class ThreadWrap {public:    ThreadWrap(std::thread& threadObj) : _thread(threadObj) {}    ~ThreadWrap() {        if (_thread.joinable()) {            _thread.detach();        }    }private:    std::thread& _thread;};void thread_fun_cb() {    for (int i = 0; i < 1000; i++) {        printf("Thread function running, index %d", i);        // 休眠10ms        std::this_thread::sleep_for(std::chrono::milliseconds(10));    }}int main() {    // 创建线程对象    std::thread testThread(thread_fun_cb);    ThreadWrap wrapThread(testThread);    // 此处休眠10ms,给子线程执行机会    std::this_thread::sleep_for(std::chrono::milliseconds(100));    printf("Exist Main Thread");    return 0;}

上述代码执行结果如下:

未调用join/detach导致崩溃解决方案结果

上诉执行结果可以看到,子线程还没结束,主线程退出了,但是没引起崩溃。

好了,到此吧,该干活了~~~

android 开启子线程执行for循环_C++11之多线程 - Part2 Joining和Detaching的使用相关推荐

  1. android 开启子线程方法,android中开启子线程

    AndroidRuntime(673): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example/ ...

  2. python线程的注意点(线程之间执行是无序的、主线程会等待所有的子线程执行结束再结束(守护主线程)、线程之间共享全局变量、线程之间共享全局变量数据出现错误问题(线程等待(join)、互斥锁))

    1. 线程的注意点介绍 线程之间执行是无序的 主线程会等待所有的子线程执行结束再结束 线程之间共享全局变量 线程之间共享全局变量数据出现错误问题 2. 线程之间执行是无序的 import thread ...

  3. node开启子线程_真Node多线程

    本文测试使用环境: 系统:macOS Mojave 10.14.2 CPU:4 核 2.3 GHz Node: 10.15.1 从 Node 线程说起 一般人理解 Node 是单线程的,所以 Node ...

  4. Java如何等待子线程执行结束

    参考:http://www.jiacheo.org/blog/262 工作中往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完后再把那段逻辑的处理结果进行汇总的产景, 这时候就需要使用线程了 ...

  5. java 线程执行结束_Java_如何等待子线程执行结束

    本程序的数据有可能是如下: main thread work start sub thread start working. main thread work done. now waiting su ...

  6. 面试官:如何让主线程等待所有的子线程执行结束之后再执行?我懵了

    使用Thread的join方法 package com.qcy.testThreadFinish;/*** @author qcy* @create 2020/09/09 17:05:23*/ pub ...

  7. 如何实现java主线程等待子线程执行完毕之后再执行?

    本文转自:问题:如何实现java主线程等待子线程执行完毕之后再执行? - jseven - 博客园 点击关注强哥,查看更多精彩文章呀 工作总往往会遇到异步去执行某段逻辑, 然后先处理其他事情, 处理完 ...

  8. java主线程控制子线程_CountDownLatch控制主线程等子线程执行完--Java多线程

    1.[代码]CountDownLatch控制主线程等子线程执行完--Java多线程 package com.sihuatech.common; import java.util.concurrent. ...

  9. main线程 子线程 顺序_在主线程main中开启子线程thread示例

    主线程中开启子线程代码实例: 创建CancleThread类 继承 Thread,对run()方法进行重写代码实例: class CancleThread extends Thread { priva ...

最新文章

  1. MYSQL 查询数据排序数据和分组数据
  2. 对象拷贝 Apache BeanUtils与Spring BeanUtils性能比较
  3. 常考数据结构与算法:表达式求值
  4. placement new 操作符
  5. python常用模块(一)
  6. 【转帖】漫话C++0x(四) —- function, bind和lambda
  7. centos 7.0 ln命令 和chkconfig 命令介绍 开机自动启 服务
  8. 福建省考计算机专业,2020福建省考,这些报考专业问题你清楚吗?
  9. 字段连接select语句
  10. IDEA 中生成 MyBatis 逆向工程实践
  11. Redhat=》中文
  12. 阿里云数据传输服务低价不低质,服务再升级 1
  13. Sql Full-Text Filter
  14. C#捕获摄像头进行拍照和录像资料总结
  15. 怎么创建java项目?新建java项目的步骤
  16. [android]qq输入法手机版 v1.0 build0580,腾讯Android版手写输入法惊艳亮相 手写更畅快...
  17. java ctor_.ctor,.cctor 以及 对象的构造过程
  18. 不是吧!你还在手动拉窗帘?
  19. Springboot集成百度地图实现定位打卡功能
  20. Java中常见的各种锁-超全面

热门文章

  1. 99+好友共同关注,公众号推荐
  2. Java编程中忽略这些细节,Bug肯定找上你
  3. 华为云开天aPaaS 上线,服务千万开发者,使能行业场景化创新
  4. 技术分享丨华为鲲鹏架构Redis知识二三事
  5. 【华为大咖分享】3.如何做Code Review 与 结对编程?
  6. oracle存储tar,Linux环境使用TAR命令快速部署安装Oracle
  7. python将学号与成绩匹配_用Python运维网络(1):基础知识
  8. python磁盘io_Python多线程同步、互斥锁、死锁
  9. Android VideoView播放视频遇到的问题
  10. Pandas出现KeyError及其分析解决