叉子的流量,我有多少个叉子?

Flow of the fork, how many forks do I have?

我已经执行了这段代码。 我知道消息的顺序是任意的(因为我明确没有使用信号量) 我的程序流程看起来如何,为什么?

父级被执行所以"baz"被打印一次。有人可以解释为什么不打印 "bar" 吗?为什么我得到 "foo" (if 语句为真)两次而不是一三次(不是我想要这个,但我想了解逻辑)(因为一位同事说我应该得到三次 foo出来)?

#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
int main() {
  int p;
  p = fork();
  if (fork()==0) {
    if (execl("/bin/echo", "/bin/echo", "foo", 0) == -1) {
      fork();
    }
  printf("bar\n");
  }
  else {
    if (p!=0) execl("/bin/echo", "/bin/echo", "baz", 0);
  }
}

execl 不是 return,而是用 /bin/echo 替换整个过程映像。 因此 "bar" 为零。

    if (execl("/bin/echo", "/bin/echo", "foo", 0) == -1) {
      fork();
    }
    /* Not reached if execl succeeded.
    Because the exec family of functions replace the process image with
    another executable.  Flow will never return, unless there is an
    error. */
    printf("bar\n");

有两个"foo"。

  int p;
  p = fork();
  /* Two processes now */
  if (fork()==0) {
      /* Two child processes here. */
      execl("/bin/echo", "/bin/echo", "foo", 0); /* (Simplification) */
      /* Two (/bin/echo foo) here, flow will never return back */
  }

有一个"baz"。

int p;
p = fork();
/* if block removed for simplicity */
if (p != 0)
{
    /* Only the initial parent process. */
    execl("/bin/echo", "/bin/echo", "baz", 0);
}

首先您需要了解 exec 系列系统调用将整个程序替换为其他程序。在您的例子中,"echo" 程序。 execl 调用之外的任何内容都不会执行。

这是正在发生的事情:

  1. 你的父进程(称之为 p0)执行 p=fork() 分叉一个克隆进程 p1.
  2. 再次执行 p0 if (fork()==0) fork 另一个克隆进程 p2.
  3. p0 然后执行打印 "baz".

  4. 的 else 语句的主体
  5. 被fork后,p1执行fork另一个进程p3if (fork()==0)语句.像p0一样,p1会进入else语句但不会打印"baz",因为p是在p0 分叉 p1 实际上等于 0(因为 p1 是 p0).

  6. p2 进入 if 语句体并执行 execl 函数,用打印 "foo" 的 echo 程序替换当前程序。

  7. 和p2一样,p3进入if语句体,执行execl函数替换当前程序与打印 "foo".

  8. 的 echo 程序

第一个fork创建了两个进程, 然后两者都做第二个叉子。

p0    (p=$pid)              //first fork
                p1  (p==0)  

   p01                p11      //second fork
      exec              exec

在叶子 children(p01p11)中,第二个 fork 后跟一个 exec,如果成功,结束旧过程映像。这应该在 stdout.

上给你两个 foo

parents(p0p1)然后执行:

if (p!=0) execl("/bin/echo", "/bin/echo", "baz", 0);

p!=0 测试可能仅在 p0 中成功(原始过程)。 这应该在 stdout.

上给你一个 baz

(在实际代码中你还应该检查 fork 错误)。