如果我在父母和孩子中分叉和执行会怎么样?

时间:2017-04-12 22:10:47

标签: c linux fork exec execl

这是我的示例代码,名为server.c(已删除include以保持简单)。

int main()
{
    for(int i = 0; i < 10; i++) {
        fork();
        execl("./client", "./client", NULL);
    }
    if (wait(NULL) == -1)
        perror("error with wait");
    return 0;
}

这是从上述程序执行的客户端代码。

int main()
{
    printf("This is the child with pid = %d from parent %d", getpid(), getppid());
    return 0;
}

现在让我解释一下我认为会发生什么以及我实际得到的是什么。

在服务器中,我们进入for循环。在第一次迭代中,我们命中了fork()。此时有两个过程即父母和第一个孩子。现在我们从这两个进程中执行一个名为“client”的程序。此客户端代码只打印一些信息。所以,当我运行这个服务器程序时,我最终会得到两行吗?来自父母的一行和来自孩子的另一行?但我只打印了一行,在使用strace之后,我发现只有父母打印的是东西,而不是孩子。那为什么会这样?

是不是因为父母已经死了(这是正确的术语?)因为它被执行了,所以不能再收集孩子了吗?如果是这样,孩子会怎么样?它变成了僵尸吧?它会被init收集吗?即便如此,为什么它不会像僵尸一样打印出那条线?

2 个答案:

答案 0 :(得分:0)

  

如果stdout连接到终端,它应该是行缓冲的,因此不需要刷新。并且所有流都在它们关闭时自动刷新,这在程序结束时发生。

也许你看到两个印刷品在同一行? 试试这段代码:

#include <stdio.h>
int main(int argc, char **argv) {
  printf("This is the child with pid = %d from parent %d\n", getpid(), getppid());
  return 0;
}

顺便说一句,您在%d中错过了printf

答案 1 :(得分:0)

你绝对应该得到两行。

如果你不是,那可能是由于你运行程序的方式。家长可以打印并退出,如果您在此时停止观看或收听,您将丢失来自孩子的信息。

因此,请确保直接从shell终端运行脚本,而不是从IDE,编辑器或任何其他工具运行脚本的一部分。

例如,这里是./server; echo "Done"的输出:

user ~ $ ./server; echo "Done."
This is the child with pid = 27904 from parent
Done.

这使得它看起来只有一行输出。但是,在此之后的行中,提示已返回,子进程在其后面写了一些信息:

user ~ $ This is the child with pid = 27905 from parent

如果以shell等待的方式运行脚本,例如添加| cat将等待管道完全关闭,您可以更清楚地看到它们:

user ~ $ ./server | cat; echo "Done."
This is the child with pid = 27953 from parent
This is the child with pid = 27955 from parent
Done.