在联接线程上调用pthread_cancel会导致 Linux 下的段错误

Calling pthread_cancel on a join'ed thread causes segfault under linux

本文关键字:Linux 段错误 错误 线程 接线 调用 cancel pthread      更新时间:2023-10-16

以下代码在第一次调用pthread_cancel时以分段错误结束,但仅在 Linux 下。在Mac OS下,它运行良好。我是否不允许在已完成运行的线程上调用pthread_cancel?也许我根本不应该打电话给pthread_cancel?

#include <iostream>
#include <pthread.h>
using namespace std;

void* run(void *args) {
   cerr << "Hallo, Running" << endl;
}   
int main() {
    int n = 100;
    pthread_t* pool = new pthread_t[n];
    for(int i=0;i<n;i++) {
        pthread_t tmp;
        pthread_create(&tmp,NULL,&run,NULL);
        pool[i] = (tmp);
    }
    for(int i=0;i<n;i++) {
        pthread_join(pool[i],0);
    }
    for(int i=0;i<n;i++) {
        pthread_cancel(pool[i]);
    }
}

参见 POSIX XSH 2.9.2:

尽管实现可能具有在系统中唯一的线程 ID,但应用程序应仅假定线程 ID 在单个进程中可用且唯一。未指定调用本卷 POSIX.1-2008 中定义的任何函数并将来自另一个进程的线程的线程 ID 作为参数传递的效果。如果线程 ID 是在将 detachstate 属性设置为 PTHREAD_CREATE_DETACHED 的情况下创建的,或者如果为该线程调用了 pthread_detach(( 或 pthread_join((,则线程 ID 的生存期在线程终止后结束。符合要求的实现可以在线程 ID 的生存期结束后自由重用线程 ID。如果应用程序尝试使用生存期已结束的线程 ID,则行为未定义。

如果线程已分离,则其线程 ID 在调用 pthread_detach(( 或 pthread_join(( 时无效用作参数。

pthread_t所引用的线程已连接后,或者如果线程在分离时终止,则不得使用。只需从程序中删除pthread_cancel代码即可。错了。 pthread_cancel用于取消正在进行的线程,并且对安全使用它而不导致资源泄漏有非常棘手的要求。对于自行退出的线程,它没有用。