有时将pthread注入运行时异常失败。如何解决?

时间:2010-04-23 04:17:32

标签: c++ pthreads signals

我尝试使用信号向线程注入异常,但有时候异常没有被捕获。例如,以下代码:

void _sigthrow(int sig)
{
    throw runtime_error(strsignal(sig));
}
struct sigaction sigthrow = {{&_sigthrow}};

void* thread1(void*)
{
    sigaction(SIGINT,&sigthrow,NULL);
    try
    {
        while(1) usleep(1);
    }
    catch(exception &e)
    {
        cerr << "Thread1 catched " << e.what() << endl;
    }
};

void* thread2(void*)
{
    sigaction(SIGINT,&sigthrow,NULL);
    try
    {
        while(1);
    }
    catch(exception &e)
    {
        cerr << "Thread2 catched " << e.what() << endl; //never goes here
    }
};

如果我尝试执行:

int main()
{
    pthread_t p1,p2;

    pthread_create( &p1, NULL, &thread1, NULL );
    pthread_create( &p2, NULL, &thread2, NULL );

    sleep(1);

    pthread_kill( p1, SIGINT);
    pthread_kill( p2, SIGINT);

    sleep(1);

    return EXIT_SUCCESS;
}

我得到以下输出:

Thread1 catched Interrupt
terminate called after throwing an instance of 'std::runtime_error'
  what():  Interrupt
Aborted

如何使第二次威胁捕获异常? 注入异常是否更好?

2 个答案:

答案 0 :(得分:2)

G ++假设异常只能从函数调用中抛出。如果您要违反此假设(例如,通过从信号处理程序中抛出它们),则需要在构建程序时将-fnon-call-exceptions传递给G ++。

但请注意,这会导致G ++:

 Generate code that allows trapping instructions to throw
 exceptions.  Note that this requires platform-specific runtime
 support that does not exist everywhere.  Moreover, it only allows
 _trapping_ instructions to throw exceptions, i.e. memory
 references or floating point instructions.  It does not allow
 exceptions to be thrown from arbitrary signal handlers such as
 `SIGALRM'.

这意味着从一些随机代码中间排除异常是绝对安全的。除了SIGSEGVSIGBUSSIGFPE之外,您只能通过-fnon-call-exceptions并且由于正在运行的代码中的错误而被触发。这在线程1上工作的唯一原因是因为由于存在usleep()调用,G ++被迫假设它可能会抛出。使用线程2,G ++可以看到没有陷阱指令,并消除了try-catch块。

您可能会发现pthread取消支持更类似于您的需要,或者只是在某处添加这样的测试:

if (*(volatile int *)terminate_flag) throw terminate_exception();

答案 1 :(得分:1)

在Boost.thread中,可以通过调用相应的boost :: thread对象的interrupt()成员函数来中断线程。它使用pthread条件变量与线程通信,并允许您在线程代码中定义中断点。我会避免在C ++中使用pthread_kill。事实上,boost线程在代码中的任何地方都没有使用pthread_kill这一事实证实了这一点。