当使用 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. $(function(){})简述

    用jQ的人很多人都是这么开始写脚本的: $(function(){ // do something }); 其实这个就是jq ready()的简写,他等价于: $(document).ready(fu ...

  2. 建立ftp服务器的网址

    https://jingyan.baidu.com/article/574c5219d466c36c8d9dc138.html

  3. MAGENTO for XAMPP install config -搬家配置与安装配置

    MEGENTO . 2.2.3 .   支持  PHP version is 7.0.2|7.0.4|~7.0.6|~7.1.0 虚拟机主机配置 环境扩展配置 其他错误 httpd-conf  ——  ...

  4. python中的__metaclass__

    什么是元类: python中类也是一种对象, 可以称为类对象. 元类就是用来创建类对象的"东西". 你创建类就是为了创建类的实例对象, 不是吗? 但是我们已经学习了python中的 ...

  5. Token防止表单重复提交和CSRF攻击

    Token,可以翻译成标记!最大的特点就是随机性,不可预测,一般黑客或软件无法猜测出来. Token一般用在两个地方: 1: 防止表单重复提交 2: anti csrf攻击(Cross-site re ...

  6. 深入浅出mybatis之启动详解

    深入浅出mybatis之启动详解 MyBatis功能丰富,但使用起来非常简单明了,今天我们来追踪一下它的启动过程. 目录 如何启动MyBatis 如何使用MyBatis MyBatis启动过程 如何启 ...

  7. 【JS】CharToAsciiToBinaryToAsciiToChar

    <!DOCTYPE html> <html> <head> <script src="/jquery/jquery-1.11.1.min.js&qu ...

  8. Permission denied的解决办法

    在运行TensorFlow Example的mnist_dataset_intro时出现了Permission denied的问题,这一看就是权限问题. 解决的办法: $ sudo chmod -R ...

  9. 【easy】695. Max Area of Island

    题目: Given a non-empty 2D array grid of 0's and 1's, an island is a group of 1's (representing land) ...

  10. ul li 实现层级列表显示

    实现效果如下: 实现要求具体如下: 1.标题有序号 上图标记1 2.标题下面的子集标题要有一定的缩进,且子集标题也有一定的序号,上图标记 2 3.如果子集标题内容过长,换行的时,开始的位置不能超过对应 ...