pthread_kill引起的分段错误

时间:2011-12-12 23:15:24

标签: c linux pthreads segmentation-fault posix

GDB告诉我pthread_kill在我的程序中导致了分段错误。基本上我正在使用pthread_kill检查一个线程是否存活,并给出了它的ID。

我一直在网上搜索,发现当TID无效时,pthread_kill可能导致分段错误。是的,我一直在使用“无效”(由我设计)类型int的TID来测试我的程序。这可能是真正的原因吗?

2 个答案:

答案 0 :(得分:14)

pthread_t不是线程ID或数字索引。它是一种不透明的类型。弥补价值可能会导致崩溃。

在Linux NPTL上,pthread_t用作指针:

int
__pthread_kill (threadid, signo)
     pthread_t threadid;
     int signo;
{
  struct pthread *pd = (struct pthread *) threadid;

应该相当清楚已经出现问题的地方:)请注意,这个指针也是一个实现细节 - 较旧的Linuxthreads实现使用数字索引到表中,你可以确实组成TID而不期望事情发生崩溃。

你需要自己跟踪线程生死。在您成功致电pthread_t之前,pthread_join有效。如果您想测试有效 pthread_t是否还活着,请在其上调用pthread_tryjoin_np;如果它返回EBUSY,则线程处于活动状态。如果函数成功, pthread_t不再有效;你不能在这一点上重复使用它 - 所以你必须在某个地方记下那个线程现在已经死了,而且不需要再检查它了!

当然,你可以实现自己的跟踪系统 - 在一个活泼的地方创建一个表,一个用于分发TID的系统,并将它们传递给新创建的线程。让每个线程在退出之前将自己标记为死(可能使用pthread_cleanup_push,以便处理线程取消和pthread_exit),并分离线程,这样您就不需要加入它(使用{{1} })。现在,您可以明确控制线程死亡报告。

答案 1 :(得分:1)

为了解决我的代码中的这个限制,我在代码未运行时将TID设置为零

memset(&thread, '\0', sizeof(pthread_t)); 

... 并在调用pthread_kill

之前检查它是否为null
//this code will run if thread is not valid
if (!thread || ESRCH == pthread_kill(thread, 0)) {
    //do stuff and create the thread
}