C++11多线程运行报错:terminate called without an active exception

1. 背景

在debug项目代码时,发现程序总是发生挂死问题,提示terminate called without an active exception,根据网上资料,大概定位到是std::thread析构函数引起。有同事大量使用std::thread创建线程,例如:

m_thread = std::thread([this]() {
	this->run();
});

而挂死原因正是因为这段代码使用不规范。

2.原因

2.1 挂死处

查看C++11 thread类实现的源码,可以看到当线程对象析构时,会检查线程的joinable状态,若为joinable,则会调用terminate抛出异常,也就是terminate called without an active exception。

~thread() _NOEXCEPT
{	// clean up
	if (joinable())
		_XSTD terminate();
}

2.2 线程对象状态及转换

C++11中,线程对象(std::thread)创建后,有两种状态:joinable、
nonjoinable。
代表该线程是否是可执行状态。
joinable : 代表该线程是可执行线程。
nonjoinable:该线程为非不可执行线程,通常一下几种情况会导致线程成为nonjoinable。

     1) 由thread的缺省构造函数构造而成(thread()没有参数)。

     2) 该thread被move过(包括move构造和move赋值)

     3) 该线程调用过join或者detach

其中线程状态经过join或者detach后,将从joinable状态转化为nonjoinable状态。可以看到,我这边的代码并没有进行join或detach,所以当线程对象析构时,将发生上述挂死问题。
线程状态转换

3.解决思路

思考了以下几种解决方法:
1.detach线程,将线程分离,线程将自行负责资源回收等操作,但缺点也很明显,当分离线程中存在与父线程一起使用的共享资源,在父线程被销毁后,分离线程继续使用,会发生程序崩溃等问题。
2.join线程,阻塞式等待,缺点同样明显,如果线程长时间未结束,则需要等待很久,阻塞程序。
3.将需要异步线程中执行的业务,统一放到线程池中执行,则能避免上述问题!

最后,统一选择使用线程池执行异步任务。

  • 12
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值