无法捕获std::线程构造函数引发的异常 我有一个C++程序,它通过SETLIME实现内存限制。根据参数的不同,它可能会在我想要处理的不同位置抛出std::bad_alloc
我通过std::thread使用多个线程。我有一些这样的代码:无法捕获std::线程构造函数引发的异常 我有一个C++程序,它通过SETLIME实现内存限制。根据参数的不同,它可能会在我想要处理的不同位置抛出std::bad_alloc,c++,multithreading,exception,C++,Multithreading,Exception,我通过std::thread使用多个线程。我有一些这样的代码: std::thread* worker; try { worker=new std::thread[NUM_THREADS]; for(int i=0;i<NUM_THREADS;++i) { worker[i]=std::thread(&ThisClass::SomeMemberFunc, this, SomeArg...); } } catch(...) {
std::thread* worker;
try
{
worker=new std::thread[NUM_THREADS];
for(int i=0;i<NUM_THREADS;++i)
{
worker[i]=std::thread(&ThisClass::SomeMemberFunc, this, SomeArg...);
}
}
catch(...)
{
std::cout << "exception in thread creation" << std::endl;
}
当我使用gdb并在abort()处设置断点时,回溯看起来像:
#0 __GI_abort () at abort.c:53
#1 0x00007ffff717269d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff7170846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7170873 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7127cfb in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff73c2e9a in start_thread (arg=0x7ffff3e86700) at pthread_create.c:308
#6 0x00007ffff6bd93fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#7 0x0000000000000000 in ?? ()
现在,这怎么可能呢?线程不会捕获彼此的异常。没有“父”线程的概念,因为在“子”线程中抛出异常时,这样的线程可能已经不存在了
如果需要线程传递异常,则需要通过将
SomeMemberFunc
包装在try-catch块中,并将捕获的异常复制到“parent”线程的一个变量(稍后在该变量中重试)来实现。请注意,您需要在其他线程运行时阻止调用线程(“父线程”),以强制执行层次结构(线程本身可以被重用以并行调用SomeMemberFunc
中的一个,这样您就不会完全浪费线程)。实际上,引发异常的是SomeMemberFunc
nosid建议使用std::async
而不是std::thread
来捕获调用端的异常
我决定通过
std::current_exception()
将SomeMemberFunc
引发的异常存储在std::exception_ptr
中。加入线程后,我检查异常指针。如果写入cout
抛出该怎么办?我看起来好像异常是从新创建的线程中的SomeMemberFunc
抛出的,而不是从线程构造函数本身抛出的。你能把SomeMemberFunc
的主体包装成一个try-catch块吗?不是答案,而是使用std::vector
而不是std::thread*
。谢谢Alan和nosid。事实上是某个人扔的。我已经怀疑过这一点,并且有一个函数try/catch围绕着它。但我完全忽略了这一点,事实上,我在接球区的一部分处理可能会再次抛出。我有8个小时无法回答自己的问题……你可以尝试使用std::async(std::launch::async,…)
而不是std::thread
。使用前者,您还可以在调用端捕获异常。
#0 __GI_abort () at abort.c:53
#1 0x00007ffff717269d in __gnu_cxx::__verbose_terminate_handler() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#2 0x00007ffff7170846 in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#3 0x00007ffff7170873 in std::terminate() () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#4 0x00007ffff7127cfb in ?? () from /usr/lib/x86_64-linux-gnu/libstdc++.so.6
#5 0x00007ffff73c2e9a in start_thread (arg=0x7ffff3e86700) at pthread_create.c:308
#6 0x00007ffff6bd93fd in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#7 0x0000000000000000 in ?? ()