c++多线程在异常环境下的等待
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++多线程在异常环境下的等待的更多相关文章
- SQLite在多线程环境下的应用
文一 SQLite的FAQ里面已经专门说明,先贴出来.供以后像我目前的入门者学习. (7) 多个应用程序或者同一个应用程序的多个例程能同时存取同一个数据库文件吗? 多进程可以同时打开同一个数据库,也可 ...
- 多线程编程之Linux环境下的多线程(三)
前面两篇文章都讲述了Linux环境下的多线程编程基础知识,也附带了典型实例.本文主要比较一下Linux环境与Windows环境下的多线程编程区别. 看待技术问题要瞄准其本质,不管是WIN32.Linu ...
- 多线程编程之Linux环境下的多线程(二)
上一篇文章中主要讲解了Linux环境下多线程的基本概念和特性,本文将说明Linux环境下多线程的同步方式. 在<UNIX环境高级编程>第二版的“第11章 线程”中,提到了类UNIX系统中的 ...
- 多线程编程之Linux环境下的多线程(一)
一.Linux环境下的线程 相对于其他操作系统,Linux系统内核只提供了轻量级进程的支持,并未实现线程模型.Linux是一种“多进程单线程”的操作系统,Linux本身只有进程的概念,而其所谓的“线程 ...
- 多线程环境下非安全Dictionary引起的“已添加了具有相同键的项”问题
问题: 代码是在多线程环境下,做了简单的Key是否存的判断, 测试代码如下: public class Program { static Dictionary<string, Logger> ...
- Java CAS同步机制 原理详解(为什么并发环境下的COUNT自增操作不安全): Atomic原子类底层用的不是传统意义的锁机制,而是无锁化的CAS机制,通过CAS机制保证多线程修改一个数值的安全性。
精彩理解: https://www.jianshu.com/p/21be831e851e ; https://blog.csdn.net/heyutao007/article/details/19 ...
- 多线程环境下的UI异步操作
转自原文 多线程环境下的UI异步操作 解决VS中,线程间不可互操作的问题,一揽子解决方案: 一.首先,定义一个类:SetControlProperty using System.Reflection; ...
- 单例模式在多线程环境下的lazy模式为什么要加两个if(instance==null)
刚才在看阿寻的博客”C#设计模式学习笔记-单例模式“时,发现了评论里有几个人在问单例模式在多线程环境下为什么lazy模式要加两个if进行判断,评论中的一个哥们剑过不留痕,给他们写了一个demo来告诉他 ...
- C#多线程环境下调用 HttpWebRequest 并发连接限制
C#多线程环境下调用 HttpWebRequest 并发连接限制 .net 的 HttpWebRequest 或者 WebClient 在多线程情况下存在并发连接限制,这个限制在桌面操作系统如 win ...
随机推荐
- excel省市区三级分类级联
前言:同事正好需要一个这样的地址类型给用户使用下载模板,改好地址再导入,这样就不会出现地址不匹配问题.所以就自己也整理了一套,以备不时之需. 效果展示: 图一:省级 图二:市级 图三:区级 图四:各乡 ...
- 快用Visual Studio(一)- 打开文件
在命令行中使用Visual Studio code打开文件: 打开Visual Studio code: CMD + SHIFT + P打开控制面板: 键入"shell command&qu ...
- 学Git,用Git ②
之前介绍了git的最核心功能游戏存档式的本地版本管理.这会我们介绍git剩下的两个核心功能:分支和远程仓库. 1.Git游戏存档进化版--Git分支 git分支的思想很有意思,git允许我们可以随时从 ...
- hadoop2对应的eclipse插件使用
1. eclipse插件安装步骤: a).把插件复制到eclipse安装目录plugins文件夹下 b).打开eclipse的Window---Preference---Hadoop M/R---指向 ...
- cogs 896. 圈奶牛
★★☆ 输入文件:fc.in 输出文件:fc.out 简单对比 时间限制:1 s 内存限制:128 MB 描述 农夫约翰想要建造一个围栏用来围住他的奶牛,可是他资金匮乏.他建造的围栏必 ...
- Ansible Playbooks 常用模块
官网链接:https://docs.ansible.com/ansible/latest/modules/list_of_all_modules.html ansible python module ...
- winlog
下载 https://www.elastic.co/downloads/beats/winlogbeat PS C:\Users\Administrator> cd 'C:\Program Fi ...
- .net 获取当前电脑账户
string domainAndName = User.Identity.Name; ] { '\\' }, StringSplitOptions.RemoveEmptyEntries); strin ...
- 今天 学习用到的一些知识(properties 读取,js 删除元素)
1.properties文件位置的关系:当properties文件放在src目录下时,编译会自动把src里的文件放到bin文件平级,因此可用this.getClass.getClassLoader.g ...
- web项目整合Shiro框架
1.修改pom.xml文件 <dependency> <groupId>org.apache.shiro</groupId> <artifactId>s ...