GDB告诉我pthread_kill
在我的程序中导致了分段错误。基本上我正在使用pthread_kill
检查一个线程是否存活,并给出了它的ID。
我一直在网上搜索,发现当TID无效时,pthread_kill
可能导致分段错误。是的,我一直在使用“无效”(由我设计)类型int
的TID来测试我的程序。这可能是真正的原因吗?
答案 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
}