我正在尝试了解c++在Linux环境中pthread_cancel的用法。但是我正在下面运行时问题。

class A {
    public:
        A(){cout<<"constructor\n";}
        ~A(){cout<<"destructor\n";}
};
void* run(void* data) {
    A a;
    while(1) {
        //sleep(1);
        cout<<"while\n";
    }
}
int main() {
    pthread_t pid;
    pthread_create(&pid,NULL,run,NULL);
    sleep(2);;
    pthread_cancel(pid);
    cout<<"Canceled\n";
    pthread_exit(0);
}

输出:
   constructor
    while
    "
    "
    while
    Canceled
    FATAL: exception not rethrown
    Aborted (core dumped)

核心文件分析:
(gdb) where
#0  0x00000036e8c30265 in raise () from /lib64/libc.so.6
#1  0x00000036e8c31d10 in abort () from /lib64/libc.so.6
#2  0x00000036e9c0d221 in unwind_cleanup () from /lib64/libpthread.so.0
#3  0x00000036fa69042b in std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) () from /usr/lib64/libstdc++.so.6
#4  0x00000000004009c5 in run(void*) ()
#5  0x00000036e9c0677d in start_thread () from /lib64/libpthread.so.0
#6  0x00000036e8cd49ad in clone () from /lib64/libc.so.6

但是,如果我在线程函数运行中取消注释sleep(1),则将得到以下输出。
构造函数
尽管
取消
析构函数

您能否解释一下为什么程序在第一种情况下而不是在第二种情况下给出“致命:不重新抛出异常”?并请举例说明为什么pthread_cancel比pthread_kill更安全?

最佳答案

我的猜测是,这与取消点有关。默认情况下,新线程的取消类型为PTHREAD_CANCEL_DEFERRED。这意味着,除非线程达到预定义的取消点之一,否则pthread_cancel不会执行任何操作。 sleep是已定义的取消点之一,但std::cout::operator<<不是(pthreads的手册页列出了所有取消点)。因此,当您将sleep注释掉时,该线程永远不会到达取消点,而pthread会抛出合适的值。您也许可以使用pthread_setcanceltype将线程设置为PTHREAD_CANCEL_ASYNCHRONOUS,但这至少会在我的系统上引起问题。

最好的选择可能是使用std::thread而不是直接处理pthreads。该库实际上是为与C++正常工作而设计的。

关于c++ - 致命的: exception not rethrown in c++,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/34972909/

10-09 08:26
查看更多