c++11开始支持多线程编程,相关的类和函数封装在标准库头文件<thread>中,而c++多线程编程很重要的一点就是当用户创建一个std::thread对象,关联了可调用对象后,需要在该thread对象销毁前调用join()或detach()。其中join()函数用于结合线程,确保在创建该thread对象的函数退出前,该线程执行完毕;而detach()函数则表示分离线程,即让线程在后台运行,线程的所有权和控制权交给c++运行时库。若thread对象销毁前没有调用join()或detach(),则程序会被终止(thread的析构函数调用std::terminate() )。

如果用户要分离线程,那么一般情况下在线程启动后立即调用detach()即可。但若需要等待线程,那么调用join()的时机就很重要:如果线程在开始之后、调用join()之前发生了异常,则join()的调用就会被跳过。保证线程在异常环境下的等待的方法之一是使用try/catch语句块:

 #include <thread>
#include <stdexcept> using std::thread;
using std::runtime_error; void func(); void TestThread() {
thread thrd(func);
try
{
//...
}
catch (runtime_error re)
{
thrd.join();
throw re;
}
thrd.join();
}

但是很显然,使用try/catch语句块很罗嗦,且容易将作用域弄乱。一个更好的方法是使用资源获取即初始化(Resource Acquisition Is Initialization, RAII)的方法,RAII是C++的一种管理资源、避免泄漏的惯用法。C++标准保证任何情况下,已构造的对象最终会销毁,即它的析构函数最终会被调用。简单的说,RAII 的做法是使用一个对象,在其构造时获取资源,在对象生命期控制对资源的访问使之始终保持有效,最后在对象析构的时候释放资源。

使用RAII的代码如下:

 #include <thread>

 using std::thread;

 void func();

 class Thread_RAII {
private:
thread &thrd;
public:
explicit Thread_RAII(thread &p_thrd) : thrd(p_thrd) {}
~Thread_RAII()
{
if (thrd.joinable())
{
thrd.join();
}
}
Thread_RAII(const Thread_RAII &) = delete;
Thread_RAII & operator=(const Thread_RAII &) = delete;
}; void TestThread()
{
thread thrd(func);
Thread_RAII tr(thrd);
//...
}

当函数TestThread()执行到末尾时,局部对象按照构造的逆序进行销毁,因此tr首先被销毁,于是其中的thrd对象被结合,即使在之前其中的某条语句执行时引发异常而退出时也是如此。

上述代码还有两点需要注意:

①析构函数在调用join()之前需要检查thrd是否是joinable()的,因为对于一个线程,join()只能调用一次。

②Thread_RAII类的拷贝构造函数及拷贝复制运算符是删除的,这是因为thread对象和unique_ptr一样是不可拷贝的(但可以移动)。

c++多线程在异常环境下的等待的更多相关文章

  1. SQLite在多线程环境下的应用

    文一 SQLite的FAQ里面已经专门说明,先贴出来.供以后像我目前的入门者学习. (7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 多进程可以同时打开同一个数据库,也可 ...

  2. 多线程编程之Linux环境下的多线程(三)

    前面两篇文章都讲述了Linux环境下的多线程编程基础知识,也附带了典型实例.本文主要比较一下Linux环境与Windows环境下的多线程编程区别. 看待技术问题要瞄准其本质,不管是WIN32.Linu ...

  3. 多线程编程之Linux环境下的多线程(二)

    上一篇文章中主要讲解了Linux环境下多线程的基本概念和特性,本文将说明Linux环境下多线程的同步方式. 在<UNIX环境高级编程>第二版的“第11章 线程”中,提到了类UNIX系统中的 ...

  4. 多线程编程之Linux环境下的多线程(一)

    一.Linux环境下的线程 相对于其他操作系统,Linux系统内核只提供了轻量级进程的支持,并未实现线程模型.Linux是一种“多进程单线程”的操作系统,Linux本身只有进程的概念,而其所谓的“线程 ...

  5. 多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题

    问题: 代码是在多线程环境下,做了简单的Key是否存的判断, 测试代码如下: public class Program { static Dictionary<string, Logger> ...

  6. Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。

    精彩理解:  https://www.jianshu.com/p/21be831e851e ;  https://blog.csdn.net/heyutao007/article/details/19 ...

  7. 多线程环境下的UI异步操作

    转自原文 多线程环境下的UI异步操作 解决VS中,线程间不可互操作的问题,一揽子解决方案: 一.首先,定义一个类:SetControlProperty using System.Reflection; ...

  8. 单例模式在多线程环境下的lazy模式为什么要加两个if(instance==null)

    刚才在看阿寻的博客”C#设计模式学习笔记-单例模式“时,发现了评论里有几个人在问单例模式在多线程环境下为什么lazy模式要加两个if进行判断,评论中的一个哥们剑过不留痕,给他们写了一个demo来告诉他 ...

  9. C#多线程环境下调用 HttpWebRequest 并发连接限制

    C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...

随机推荐

  1. spring手动配置

    本文总结自:https://www.cnblogs.com/V1haoge/p/7183408.html SpringBoot中免除了大部分配置,但是对于一些特定的情况,还是需要我们进行手动配置的. ...

  2. 20145307JAVA学习期末总结

    20145307<Java程序设计>课程总结 每周读书笔记链接汇总 20145307 <Java程序设计>第一周学习总结:http://www.cnblogs.com/Jcle ...

  3. params

    using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace Ch06 ...

  4. PHP 根据IP地址获取所在城市

    header('Content-Type:text/html;Charset=utf-8'); function GetIp(){ $realip = ''; $unknown = 'unknown' ...

  5. LeetCode—— Partition Equal Subset Sum

    Question Given a non-empty array containing only positive integers, find if the array can be partiti ...

  6. 转载 - POJ分类很好很有层次感

    from http://blog.csdn.net/zzycsx/article/details/49103451 OJ上的一些水题(可用来练手和增加自信) (poj3299,poj2159,poj2 ...

  7. Extjs前端框架解决了什么问题

    Extjs 作为一套企业级富客户端前端开发框架,主要解决了以下问题: 1.DOM Ext.Element: Ext.Element.get()快捷方式Ext.get(),只能以dom的id作为参数去获 ...

  8. Huffuman Coding (哈夫曼编码)

    哈夫曼编码(Huffman Coding),又称霍夫曼编码,是一种编码方式,哈夫曼编码是可变字长编码(VLC)的一种.Huffman于1952年提出一种编码方法,该方法完全依据字符出现概率来构造异字头 ...

  9. MySQL表锁和行锁

    锁粒度 MySQL 不同的存储引擎支持不同的锁机制,所有的存储引擎都以自己的方式显现了锁机制,服务器层完全不了解存储引擎中的锁实现: InnoDB 存储引擎既支持行级锁(row-level locki ...

  10. 索引选择性与cardinality

    索引选择性 索引选择性是索引基数(cardinality)与表中数据行数(n_row_in_table)的比值,即 索引选择性=索引基数/数据行 其中cardinality是索引中不重复记录的预估值. ...