当我读apue v3的时候,更具体地说,我发现自己无法掌握一些东西。
首先,让我们假设我在unix shell中运行以下管道程序:

cat /etc/passwd | grep -i alex | awk -F : '{print $3}' | less

在第一个示例中,假设我使用的是一个不知道作业的shell(sh)
这本书解释了,在这种情况下,最终的ps-o pid、ppid、pgid、comm会是这样的(假设shell的pid是10,ppid是5)
PID     PPID     PGID     COMM
10       5       10        sh
11       10      10        less
12       11      10        cat /etc/passwd
13       11      10        grep -i alex
14       11      10        awk -F : '{print $3}'

在第二个示例中,假设我们使用了一个作业感知shell(bash):
PID      PPID     PGID     COMM
10       5       10        bash
11       10      11        cat /etc/passwd
12       10      11        grep -i alex
13       10      11        awk -F : '{print $3}'
14       10      11        less

问题是,为什么在第二种情况下,进程是shell的子进程,而不是最后一个进程的子进程(与第一种情况一样),并且假设shell为其每个子进程接收一个sigchld,那么子进程之间是否会发生某种种族状况?
很抱歉缩进错误。我现在就去修
谢谢,
亚历克斯

最佳答案

问题是,为什么在第二种情况下,进程是shell的子进程,而不是最后一个进程的子进程[…]
因为那是正确的行为。只有shell中的一个bug可以解释为什么less将成为管道中其他进程的父进程。less无法处理其他进程的sigchld,因为它尚未启动它们。(更重要的是,这也会由于less中的syscall失败并出现eintr错误而导致问题。)这也意味着除了less之外的所有进程都将被pid 1而不是shell捕获,因为它将接收它们的SIGCHLD
否则,进程的父子关系与“作业感知外壳”无关。作业感知shell做两件事:它实现作业控件(jobsfgbg命令)并将自己设置为会话领导者(使用setsid()系统调用),这样sighup将在它(shell)终止时自动发送到所有子进程。
[…]假设Shell为它的每个孩子都收到了一个sigchld,难道孩子之间不存在某种种族状况吗?
竞争条件是指事物执行的顺序不符合预期的情况。在这里,没有预期的订单。大多数过滤器应用程序(如grep:从stdin读取、写入stdout等过滤器)在stdin上看到eof时会立即终止。通常,管道中的第一个进程可能在最后一个进程看到任何输入时已经终止。这很正常。它们被收割了,但是它们的输出已经被送到管道中,并且会被正常处理。

09-30 13:07
查看更多