当使用 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. monkey自定义脚本实践

    自定义脚本的稳定性测试 常规Monkey测试执行的是随机的事件流,但如果只是想让Monkey测试某个特定场景这时候就需要用到自定义脚本了,Monkey支持执行用户自定义脚本的测试,用户只需要按照Mon ...

  2. 记录腾讯云中矿机病毒处理过程(重装系统了fu*k)

    刚想学学kafka,登录与服务器看看把,谁知ssh特别慢,很奇怪,我以为是我网速问题,断了wifi,换了网线,通过iterm想要ssh root@x.x.x.x,但是上不去? 就tm的很奇怪了,登录腾 ...

  3. Android 6.0以上动态获取权限

    首先在清单文件中注册 然后在MainActivity.java中将权限封装到一个String数组中 static final String[] PERMISSION = new String[]{ M ...

  4. 阶梯Nim问题

    问题形式 有\(n\)个位置\(1...n\),每个位置上有\(a_i\)个石子.有两个人轮流操作.操作步骤是:挑选\(1...n\)中任一一个存在石子的位置\(i\),将至少1个石子移动至\(i-1 ...

  5. macOS修改Dock隐藏速度

    延迟时间 修改延迟时间改为0,默认为1. defaults write com.apple.dock autohide-delay -int 0; killall Dock 修改为浮点数值,例如0.1 ...

  6. Maven pom文件标签解析大全

    <span style="padding:0px; margin:0px"><project xmlns="http://maven.apache.or ...

  7. Git 分支 (二)合并

    分支的新建与合并 让我们来看一个简单的分支新建与分支合并的例子,实际工作中你可能会用到类似的工作流. 你将经历如下步骤:1. 开发某个网站.2. 为实现某个新的需求,创建一个分支.3. 在这个分支上开 ...

  8. Shiro与CAS整合实现单点登录

    1.简介 CAS:Yale 大学发起的一个开源项目,旨在为 Web 应用系统提供一种可靠的单点登录方法. Shiro:Apache Shiro是一个Java安全框架,可以帮助我们完成认证.授权.会话管 ...

  9. 队列优化的dijkstra

    #include<iostream> #include<queue> #include<cstdio> #include<cstring> #inclu ...

  10. ES6 + Webpack + React + Babel 如何在低版本浏览器上愉快的玩耍

    https://blog.csdn.net/a324539017/article/details/52824189