You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何对已分离线程调用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错误。

总结

  1. 你的测试场景中,子线程执行速度远快于主线程的pthread_join,线程已经退出,因此pthread_join返回成功。
  2. 分离线程的核心意义是线程退出后自动回收资源,无需其他线程调用pthread_join,但并非绝对禁止对已分离线程调用pthread_join,具体行为取决于线程是否已终止及操作系统的线程库实现。

内容的提问来源于stack exchange,提问作者Amruta Dhanawade

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 20:25:16