为何对已分离线程调用pthread_join会返回0(成功)?
为什么对已分离的线程调用pthread_join仍返回成功?
当线程通过pthread_detach标记为分离状态后,按常理似乎不应再被pthread_join等待,但你的测试代码中调用后却返回了0(成功),核心原因在于线程的执行时机和POSIX标准对该场景的未定义行为。
你的测试代码分析
先看你提供的代码和输出:
// C program to show thread functions #include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> void* func(void* arg) { int x = pthread_detach(pthread_self()); printf("x = %d\n", x); printf("Error description is : %s\n",strerror(x)); printf("Inside the thread\n"); pthread_exit(NULL); } void fun() { pthread_t ptid; pthread_create(&ptid, NULL, &func, NULL); int x = pthread_join(ptid, NULL); printf("Error description is : %s\n",strerror(x)); pthread_exit(NULL); } int main() { fun(); return 0; }
输出:
x = 0 Error description is : Success Inside the thread Error description is : Success
从输出顺序可以看到,子线程的所有输出都在主线程的pthread_join结果打印之前完成,说明子线程在主线程调用pthread_join时已经退出。此时即使线程被标记为分离状态,Linux的NPTL线程实现会认为pthread_join的等待目标(线程终止)已经完成,因此返回成功。
关键原理:POSIX的未定义行为与线程生命周期
POSIX.1-2001标准明确指出:对已分离状态的线程调用pthread_join的行为是未定义的,不同操作系统的线程库可以有不同实现:
- 如果线程已经退出:即使是分离状态,部分实现(如Linux NPTL)会允许
pthread_join返回成功,因为线程的终止状态仍可被获取,且pthread_join的核心逻辑是等待线程终止并回收资源(分离线程会自动回收,但已终止的线程资源可能尚未清理)。 - 如果线程仍在运行且已分离:此时调用
pthread_join会返回EINVAL错误(无效参数),因为分离线程不允许被连接等待。
验证:让线程在分离后持续运行
修改代码,让子线程在分离后保持运行一段时间,确保主线程的pthread_join在子线程运行时调用:
#include <pthread.h> #include <stdio.h> #include <stdlib.h> #include <errno.h> #include <string.h> #include <unistd.h> void* func(void* arg) { int x = pthread_detach(pthread_self()); printf("x = %d\n", x); printf("Error description is : %s\n",strerror(x)); sleep(1); // 让子线程持续运行 printf("Inside the thread\n"); pthread_exit(NULL); } void fun() { pthread_t ptid; pthread_create(&ptid, NULL, &func, NULL); usleep(500000); // 等待子线程完成detach操作 int x = pthread_join(ptid, NULL); printf("Error description is : %s\n",strerror(x)); pthread_exit(NULL); } int main() { fun(); return 0; }
此时输出会变成:
x = 0 Error description is : Success Error description is : Invalid argument Inside the thread
可以看到,当pthread_join在分离线程仍运行时调用,返回了预期的EINVAL错误。
总结
- 你的测试场景中,子线程执行速度远快于主线程的
pthread_join,线程已经退出,因此pthread_join返回成功。 - 分离线程的核心意义是线程退出后自动回收资源,无需其他线程调用
pthread_join,但并非绝对禁止对已分离线程调用pthread_join,具体行为取决于线程是否已终止及操作系统的线程库实现。
内容的提问来源于stack exchange,提问作者Amruta Dhanawade
相关产品推荐
相关产品推荐

