当使用 std::thread 对象执行线程时,必须要调用 join() (或者 detach(),由于 detach() 可以立即调用,所以这里只考虑 join())

 #include <iostream>
#include <thread>
#include <chrono> using namespace std; void threadInvoker()
{
cout << "thread begin\n";
this_thread::sleep_for(chrono::milliseconds());
cout << "thread end\n";
} void doSomething()
{
cout << "doSomething begin\n";
this_thread::sleep_for(chrono::milliseconds());
cout << "doSomething end\n";
} void doOther()
{
} void f()
{
thread t(threadInvoker); doSomething(); doOther();
t.join();
} int main()
{
f();
}

编译:g++ -std=c++11 -pthread test.cpp

如果 doSomething() 会产生异常,则尝试捕获

 #include <iostream>
#include <thread>
#include <chrono> using namespace std; void threadInvoker()
{
cout << "thread begin\n";
this_thread::sleep_for(chrono::milliseconds());
cout << "thread end\n";
} void doSomething()
{
cout << "doSomething begin\n";
this_thread::sleep_for(chrono::milliseconds());
throw ;
cout << "doSomething end\n";
} void doOther()
{
} void f()
{
thread t(threadInvoker); try {
doSomething();
}
catch (...) {
cout << "catch exception\n";
t.join();
return;
} doOther();
t.join();
} int main()
{
f();
}

但是必须在 catch 块里调用 t.join(),否则会 crash。如果条件一多,很可能会在某个分支下遗忘 t.join()。

因此可以使用 RAII 来避免,在析构函数中进行 join()

 #include <iostream>
#include <thread>
#include <chrono> using namespace std; class ThreadGuard
{
public:
explicit ThreadGuard(thread& t):mT(t) {}
~ThreadGuard()
{
if (mT.joinable()) {
cout << "join\n";
mT.join();
}
}
ThreadGuard(ThreadGuard const&) = delete;
ThreadGuard& operator=(ThreadGuard const&) = delete;
private:
thread& mT;
}; void threadInvoker()
{
cout << "thread begin\n";
this_thread::sleep_for(chrono::milliseconds());
cout << "thread end\n";
} void doSomething()
{
cout << "doSomething begin\n";
this_thread::sleep_for(chrono::milliseconds());
throw ;
cout << "doSomething end\n";
} void doOther()
{
} void f()
{
thread t(threadInvoker);
ThreadGuard tg(t); try {
doSomething();
}
catch (...) {
cout << "catch exception\n";
return;
} doOther();
} int main()
{
f();
}

利用局部对象的析构保证 join() 的调用

使用 RAII 完成线程等待的更多相关文章

  1. SQL之收集SQL Server线程等待信息

    要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据. sys.dm_os_wait_ ...

  2. 对线程等待函数pthread_join二级指针参数分析

    分析之前先搞明白,这个二级指针其实在函数内部是承接了上个线程的返回值. 看man手册,发现返回值是个普通指针.人家用二级指针来承接,可能准备干大事.这个可以自己搜索一下.原因嘛,二级指针是保存了这个地 ...

  3. Java多线程系列--“基础篇”05之 线程等待与唤醒

    概要 本章,会对线程等待/唤醒方法进行介绍.涉及到的内容包括:1. wait(), notify(), notifyAll()等方法介绍2. wait()和notify()3. wait(long t ...

  4. java 多线程—— 线程等待与唤醒

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  5. 收集SQLServer线程等待信息

    要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信息是进行数据库优化的依据. sys.dm_os_wait_ ...

  6. SQL点滴13—收集SQLServer线程等待信息

    原文:SQL点滴13-收集SQLServer线程等待信息 要知道线程等待时间是制约SQL Server效率的重要原因,这一个随笔中将学习怎样收集SQL Server中的线程等待时间,类型等信息,这些信 ...

  7. c/c++ 多线程 多个线程等待同一个线程的一次性事件

    多线程 多个线程等待一个线程的一次性事件 背景:从多个线程访问同一个std::future,也就是多个线程都在等待同一个线程的结果,这时怎么处理. 办法:由于std::future只能被调用一次get ...

  8. c/c++ 多线程 一个线程等待某种事件发生

    多线程 一个线程等待某种事件发生 背景:某个线程在能够完成其任务之前可能需要等待另一个线程完成其任务. 例如:坐夜间列车,为了能够不坐过站, 1,整夜保持清醒,但是这样你就会非常累,不能够睡觉. 2, ...

  9. 第三节:ThreadPool的线程开启、线程等待、线程池的设置、定时功能

    一. ThreadPool简介 ThreadPool简介:ThreadPool是一个线程池,当你需要开启n个线程时候,只需把这个指令抛给线程池,它将自动分配线程进行处理,它诞生于.Net 2.0时代. ...

随机推荐

  1. Arrays 三种基本常用法

    一:背景 jdk中为了便于开发,给开发者提供了Arrays类,其中包含了很多数组的常用操作.例如快速输出.排序.查找等 二: import java.util.Arrays; //(需要引用class ...

  2. l2tp pptp相关的一些记录

    添加用户名和密码 echo "user l2tpd password *">>/etc/ppp/chap-secrets /etc/ipsec.conf dpddela ...

  3. win+R启动列表

    屌丝才用windows,无奈~ """ Win+R 快速启动的命令: 系统应用程序: calc - 启动计算器 charmap - 启动字符映射表 chkdsk - Ch ...

  4. Java Web项目中解决中文乱码方法总结

    一.了解常识: 1.UTF-8国际编码,GBK中文编码.GBK包含GB2312,即如果通过GB2312编码后可以通过GBK解码,反之可能不成立; 2.web tomcat:默认是ISO8859-1,不 ...

  5. 学习python第二天

    编程语言分为哪几种? 1. 机器语言:是通过直接编写二进制指令对计算机下达指令的编程方式 -- 0000,0000,00000000001:加载 暂存区A 存储器地址1 2. 汇编语言:是通过编写二进 ...

  6. tensorflow 语音识别报错

    cuDnn由7.1版本改为7.4.2.24版本,成功

  7. 任意模数NTT学习笔记

    这两天有点颓,所以东西学的也很慢...这个一眼就能推出来的活生生卡了我两天.. 说几个细节: 柿子: \[f*g = (\frac{f}{M} +f\%m)*(\frac{g}{M} +g\%m) \ ...

  8. ansible基本使用方法

    一.ansible的运行流程 ansible是基于ssh模块的软件,所以主控端和被控端的ssh服务必须正常才能保证ansbile软件的可用性. 检查ssh服务是否正常:   systemctl sta ...

  9. MongoDB and GUI 管理界面

    MongoDB https://www.mongodb.com/ MongoDB AtlasDatabase as a Service The best way to deploy, operate, ...

  10. burp suite 基础入门超详细教程

    介绍: 都是我个人了解到的信息,,分享给大家 欢迎指正 burp suite 被誉为web安全工具中的瑞士军刀. 大家知道,瑞士军刀,都是体积小,功能强悍,.西方军队的标配.说这么多,只是想强调这款工 ...