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,所以当线程对象析构时,将发生上述挂死问题。
C++11多线程运行报错:terminate called without an active exception_第1张图片

3.解决思路

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

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

你可能感兴趣的:(Linux应用编程,c++,java,jvm)