多线程fork场景下Linux系统调用死锁问题排查
多线程fork-exec场景下的死锁竞态条件排查问题
背景与实现流程
近期开发了一款工具,需反复启动可执行程序,通过管道传入大量数据并分析结果。因属于计算密集型任务,使用pthreads实现多线程。工具仅启动「数据处理」应用(如sha256sum),这类应用从stdin读取数据至EOF后输出简单结果。
工具的核心执行流程如下:
- 主线程创建工作线程池,以及用于屏障/「闸门」、任务完成通知的互斥锁与条件变量,工作线程启动后进入等待状态。
- 每轮任务执行步骤:
- 主线程「打开」闸门,触发工作线程执行任务。
- 工作线程通过
fork-exec启动sha256sum,创建stdin/stdout管道;用随机数生成器填充缓冲区并写入子进程,关闭写端;读取子进程输出结果后调用wait()等待子进程结束。 - 主线程等待所有线程完成任务,处理数据并打印结果。
- 主线程发出结束信号,释放闸门并调用
join回收线程。 - 工作线程检测到结束信号后退出。
- 主线程完成所有资源清理。
问题现象
程序可通过首个参数指定线程数,当线程数大于1时,代码会迅速卡住,部分工作线程阻塞在read()、close()或wait()调用中。
使用Valgrind的DRD和Helgrind工具检测未发现问题,且在这些工具的调度下程序可正常运行(推测是工具调度更具确定性)。
已做排查
已发现线程共享pipe()创建的文件描述符问题,已处理子进程关闭未使用的继承管道(否则会导致EOF无法正常触发),但仍未解决死锁问题。
核心疑问
请问该代码中存在何种竞态条件,导致死锁?
注:已知存在更简便的实现方式(如使用哈希库而非fork-exec),但希望通过排查此问题深入学习,目前尚未找到根本原因。
内容的提问来源于stack exchange,提问作者Doddy
相关产品推荐
相关产品推荐

