为何pthread_join未阻塞调用线程?技术问题咨询
pthread_join未按预期阻塞的原因分析
我正在学习使用<pthread.h>,教材说明:
pthread_join函数会阻塞调用线程……
但在我的测试中,该函数并未阻塞调用线程,测试代码如下:
void *a_thread(void *pt) { puts("a_thread:join"); pthread_join(*(pthread_t *)pt, NULL); // <-- a_thread didn't wait for puts("a_thread:joined"); // itself to finish executing. return NULL; } int main(void) { pthread_t t; puts("create"); pthread_create(&t, NULL, a_thread, &t); puts("created"); puts("main:join"); pthread_join(t, NULL); puts("main:joined"); }
编译运行命令:gcc -Og -o test test.c; ./test
输出结果:
create created main:join a_thread:join a_thread:joined main:joined
原因分析
核心问题在于线程调用pthread_join等待自身属于未定义行为:
- POSIX标准明确规定,
pthread_join的目标线程ID必须是另一个可连接的线程,调用线程不能等待自己结束。这种情况下,操作系统没有义务按照“阻塞等待”的逻辑处理,行为完全不可预期——可能直接返回、触发崩溃,或者出现其他异常表现,你的测试中就是直接返回,没有产生阻塞。 - 你的代码里,
pthread_create将新线程的ID存储在t中,并把t的地址传给线程函数a_thread。新线程启动后,解参得到的就是自身的线程ID,相当于调用pthread_join(自己的ID, NULL),这直接违反了规范,所以不会出现预期的阻塞。 - 从输出顺序也能验证这一点:主线程先进入
pthread_join等待新线程;新线程启动后调用pthread_join等待自己,因未定义行为直接返回,打印a_thread:joined后结束;主线程检测到新线程结束,自己的pthread_join也完成,打印main:joined。
正确用法示例
如果需要实现线程间的等待,应该让一个线程等待另一个独立的线程,比如:
#include <pthread.h> #include <stdio.h> #include <unistd.h> void *worker_thread(void *arg) { puts("worker: 开始执行任务"); // 模拟耗时工作 sleep(2); puts("worker: 任务完成,退出"); return NULL; } void *waiter_thread(void *arg) { pthread_t worker_id = *(pthread_t *)arg; puts("waiter: 等待worker线程完成"); pthread_join(worker_id, NULL); puts("waiter: worker线程已退出"); return NULL; } int main(void) { pthread_t worker, waiter; pthread_create(&worker, NULL, worker_thread, NULL); pthread_create(&waiter, NULL, waiter_thread, &worker); pthread_join(waiter, NULL); puts("main: 所有线程已退出"); return 0; }
这段代码中,waiter_thread会阻塞直到worker_thread结束,符合pthread_join的预期行为。
内容的提问来源于stack exchange,提问作者shynur
相关产品推荐
相关产品推荐

