为何基于Pipe实现的双进程程序在第一子进程未结束时就终止?
为什么使用/dev/random时,主程序在第二个子进程结束后就退出?
先看你的测试场景:执行命令./a.out /dev/random "/bin/cat" "/usr/bin/head -1" o.txt时,明明/dev/random是无限输出的设备,主程序却在第二个子进程完成后就结束,核心原因和head -1的行为、Unix管道的信号机制直接相关:
- 第二个子进程运行的是
head -1,这个命令的逻辑是读取并输出一行输入后立即退出。当它退出时,会关闭管道的读端(end[0])。 - 此时主进程已经提前关闭了管道的两端(代码里的
close(end[0]); close(end[1]);),整个系统里只有第一个子进程(执行/bin/cat)还持有管道的写端(end[1])。 - 根据Unix管道的规则:当进程尝试往读端已完全关闭的管道写入数据时,内核会向该进程发送
SIGPIPE信号,而该信号的默认处理行为就是直接终止进程。 - 第一个子进程
cat此时还在从/dev/random读取数据并试图往管道写入,但管道的读端已经不存在了,所以会立刻被SIGPIPE信号杀死。 - 主进程的
waitpid(id, &status, 0)会因为第一个子进程被终止而立即返回,紧接着waitpid(id2, &status, 0)也会快速返回(第二个子进程早已退出),最终主进程执行write(1,"DOne",5)后结束。
本质上不是主进程没等第一个子进程,而是第一个子进程在第二个子进程退出后,被系统信号强制终止了,所以主进程能顺利完成等待逻辑并退出。
内容的提问来源于stack exchange,提问作者Taha Exo
相关产品推荐
相关产品推荐

