为什么不建议使用std::thread及解决方法

 

使用std::thread 创建线程, 代码逻辑如果存在某些异常,。这时候程序会产生coredump, 但是分析coredump, 会发现调用栈是缺失的,造成定位问题困难;

问题描述:

源码:

 1 #include <stdexcept>
 2 #include <thread>
 3 #include <functional>
 4 #include <iostream>
 5 #include <vector>
 6 
 7 void foo()
 8 {
 9   std::vector<int> vc;
10   std::cout << __LINE__ << vc.at(1)<< std::endl;
11 }
12 
13 int main()
14 {
15     std::thread t(foo);
16     t.join();
17 }

 

编译:

g++ -o test test.cpp -std=c++11 -pthread

 

执行结果:

 

 

 core栈信息:

 

 

 

 

问题解决:

在线程代码中添加try.. catch异常捕获

源码:

 1 #include <stdexcept>
 2 #include <thread>
 3 #include <functional>
 4 #include <iostream>
 5 #include <vector>
 6 
 7 void foo()
 8 {
 9   try{
10     std::vector<int> vc;
11     std::cout << __LINE__ << vc.at(1)<< std::endl;
12   } catch (std::exception& e){
13     std::cout << __LINE__ << " exception msg : " << e.what() << std::endl;
14     std::terminate();
15   }
16 }
17 
18 int main()
19 {
20   std::thread t(foo);
21   t.join();
22 }

 


编译:

g++ -o test test.cpp -std=c++11 -pthread

 

执行结果:

 

 core栈信息

可以定位到是foo函数引起的

 

 

原因分析:

参考:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=55917

 原因为:

libstdc++ 的std::thread 在调用的用户提供的run()函数时,外围包裹了try/catch, 当run()函数 throw 异常时,调用栈会被展开(退栈), 最后调用std::terminate(), 操作系统生成core文件, 就只能看到一部分的调用栈了。
【源码位置:libstdc++-v3/src/c++11/thread.cc】

此问题在gcc 8.1已通过移除try/catch的方式进行解决

 

 
posted @ 2022-12-13 17:15  郭流水  阅读(412)  评论(0编辑  收藏  举报