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

关于pthread_join函数阻塞主线程及多线程执行逻辑的技术咨询

pthread_join 运行逻辑详解

核心结论

pthread_join() 的核心作用就是阻塞调用它的线程(此处为你的主线程),直到指定的子线程完全终止,之后调用线程才会恢复执行后续代码。


针对你的疑问逐一解释

1. 手册描述的准确含义

Linux 手册中对 pthread_join() 的说明:

The pthread_join() function waits for the thread specified by thread to terminate

这句话的准确解读:

  • 调用 pthread_join() 的线程(比如主线程)会进入阻塞状态,暂停执行后续代码;
  • 子线程与主线程在调用 pthread_create() 后是独立并行运行的,但主线程执行到 pthread_join() 时会停在这里,必须等指定子线程跑完才会继续;
  • 不是说主线程“只能在子线程结束后才能结束”——如果主线程不调用 pthread_join(),它可以先于子线程结束,此时子线程会变成“孤儿线程”由系统接管,但你的代码里因为调用了 pthread_join(),所以主线程必须等子线程结束才能执行后续循环,最终结束进程。

2. 单线程测试的现象本质

你运行单线程代码时,子线程先跑完10000次循环,主线程才执行后续100次循环,这正是 pthread_join() 阻塞特性的体现:

  • 主线程调用 pthread_create() 后,子线程立刻开始执行 function 中的循环;
  • 主线程继续执行到 pthread_join(start, NULL),此时子线程还在运行,主线程被阻塞,暂停在此处;
  • 直到子线程完成所有循环、线程终止,pthread_join() 才会返回,主线程才会继续执行后面的for循环。

3. 多子线程时的协调逻辑

当你取消注释创建两个子线程后,Child1 和 Child2 输出交叉,且主线程要等两个子线程都结束才继续,原因如下:

  • 两次调用 pthread_create() 后,Child1 和 Child2 会被操作系统调度,并行执行(CPU会在两个线程间快速切换,所以输出交叉);
  • 主线程先调用 pthread_join(start, NULL),此时会阻塞直到 Child1 终止;
  • Child1 终止后,主线程继续执行下一行 pthread_join(start_2, NULL),再次阻塞直到 Child2 终止;
  • 只有当两个 pthread_join() 都返回后,主线程才会进入最后的100次循环。

整理后的测试代码

#define _GNU_SOURCE
#include<stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <unistd.h>
#include <assert.h>
#include <sched.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include "../utils/memory_utils.h"
#include "../utils/cache_utils.h"
#include "../utils/misc_utils.h"


void function(char *str){
   for(int i=0;i<10000;i++){
     printf("%s thread: %d\n", str, i);
   }
}


int main(){
  char *str = "string";
  pthread_t start,start_2;
   if (pthread_create(&start, NULL, (void *)function, "Child1") != 0) {
    perror("pthread_create: trojan");
  }

  if (pthread_create(&start_2, NULL, (void *)function, "Child2") != 0) {
    perror("pthread_create: trojan");
  }

   pthread_join(start, NULL);
   pthread_join(start_2, NULL);

   for(int i=0;i<100;i++){
     printf("Parent thread: %d\n", i);
   }
  
  return 0;
}

额外补充

  • 如果不想让主线程阻塞,可以不调用 pthread_join(),但要注意:主线程结束后整个进程会终止,所有子线程会被强制杀死,因此如果需要子线程完成任务,pthread_join() 是最安全的等待方式;
  • 多个 pthread_join() 的调用顺序不影响子线程的执行顺序——子线程的调度由操作系统决定,pthread_join() 只是单纯等待指定线程结束,不会干预其他线程的运行。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 01:35:27