管道和叉子,不会显示在标准输出上

时间:2012-11-25 15:04:56

标签: c linux fork stdout pipe

我正在做我的作业,即在C中复制unix命令shell。

我已经实现了直到单个命令执行后台运行(&)。

现在我正处于实现管道的阶段,我遇到了这个问题,对于大于1的管道,带有管道的子命令已经完成,但最终输出没有显示在stdout上(最后一个命令的stdin是替换为读取最后一根管道)

dup2(pipes[lst_cmd], 0);

我也在父母身上试过了fflush(STDIN_FILENO)

我程序的退出是CONTROL-D,当我按下时,输出显示(也是因为我在CONTROL-D上的操作退出(0)而退出。)

我认为管道的输出是在stdout缓冲区中,但是没有显示出来。除了fflush还有其他方法可以将缓冲区中的内容输入stdout吗?

1 个答案:

答案 0 :(得分:0)

看过代码(不公平的优势)后,主要问题是流程结构与不彻底关闭管道相结合。

管道ps | sort的流程结构是:

main shell
    - coordinator sub-shell
        - ps
        - sort

主shell创建了N个管道(ps | sort为N = 1)。然后创建协调器shell;它会启动N + 1个孩子。但是,它没有等待它们终止,也没有关闭它的管道副本。主壳也没有关闭它的管道副本。

如果没有协调器子shell,更常规的流程结构可能会发生。生成孩子有两种机制。传统上,主shell会分叉一个子进程;它将对管道中的前N个进程进行协调(包括首先创建管道),然后执行管道中的最后一个进程。主shell等待一个子进程完成,管道的退出状态是子进程的退出状态(也就是管道中的最后一个进程)。

最近,bash提供了一种机制,主shell获取管道中每个子节点的状态;它协调。

主要修复(除了一些主要是次要的编译警告)是:

  1. 主shell在分叉协调员后关闭所有管道。
  2. 主shell等待协调员完成。
  3. 协调员在分叉管道后关闭所有管道。
  4. coordinator等待管道中的所有进程完成。
  5. 协调员退出(而不是返回提供决斗双提示)。
  6. 更好的修复将消除协调器子shell(它的行为类似于所描述的经典系统)。