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

pthreads编程疑问:thread2的printf输出为何会重复?

为什么你的pthreads代码会出现thread2输出重复的情况?

这问题挺典型的,我来帮你一步步拆解原因:

核心根源:未初始化的pthread_t变量被误用

你的全局变量thread2在主线程创建它之前,默认初始化为0。当thread1被先创建并调度执行时,它会立刻调用pthread_join(thread2, NULL)——这时候传入的是一个无效的线程ID。

在你使用的Ubuntu 16.04的NPTL线程库(搭配GCC 5.4)中,pthread_join(0, NULL)有一个不符合POSIX规范的特殊行为:它不会返回错误,反而会错误地返回成功(ret=0)。这就导致thread1误以为已经join到了thread2,直接退出。

进程退出引发的输出混乱

当thread1退出后,主线程的pthread_join(thread1, NULL)完成,随即触发进程退出流程:

  • 进程会调用exit(),该函数会强制刷新所有stdio流的缓冲区。
  • 同时,进程会向所有仍在运行的线程(此时就是thread2)发送终止信号,强制它们停止。

但此时thread2可能还在执行中:

  • 它可能刚执行完第一个printf,第二个printf的内容还在用户态缓冲区里;
  • 或者它正处于printf的执行过程中,进程退出的缓冲区刷新操作和thread2自身的printf操作发生了冲突;
  • 更严重的情况是,进程退出时会回收线程的栈资源,thread2的栈被破坏后,printf的字符串指针指向的内存被重复读取或写入,导致输出重复。

这就是你看到exit from 2.....重复输出的原因。

验证逻辑的修复小实验

你可以修改代码,先创建thread2再创建thread1:

// 交换创建顺序
ret2 = pthread_create(&thread2, NULL, thread2_entry, NULL);
ret1 = pthread_create(&thread1, NULL, thread1_entry, NULL);

这样thread1执行pthread_join(thread2, NULL)时,thread2已经存在,不会再出现无效join的情况,输出也会变得稳定,不会有重复内容。

额外的实践建议

  • 永远不要使用未初始化的pthread_t变量调用pthread_join,这属于未定义行为,不同系统/库版本的表现可能差异很大。
  • 如果需要线程间的同步,优先使用条件变量、互斥锁等同步原语,而不是依赖线程创建的顺序(线程调度是完全不可预测的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 04:42:08