无法捕获std::线程构造函数引发的异常 我有一个C++程序,它通过SETLIME实现内存限制。根据参数的不同,它可能会在我想要处理的不同位置抛出std::bad_alloc

无法捕获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使用多个线程。我有一些这样的代码:

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 ?? ()