如果我在parent和child中进行fork和exec,会发生什么?

如果我在parent和child中进行fork和exec,会发生什么?,c,linux,fork,exec,execl,C,Linux,Fork,Exec,Execl,这是我的示例代码server.c(为了保持简单,我删除了include) 现在让我解释一下我认为会发生什么,以及我作为输出实际得到了什么 在服务器中,我们输入for循环。在第一次迭代中,我们使用了fork()。此时有两个进程,即父进程和第一个子进程。现在我们从这两个进程执行一个名为“client”的程序。这个客户端代码只是打印一些信息。所以当我运行这个服务器程序时,我应该得到两行代码,对吗?一行来自父母,另一行来自孩子?但我只打印了一行,在使用strace后,我发现只有家长在打印东西,而不是孩子

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

现在让我解释一下我认为会发生什么,以及我作为输出实际得到了什么

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

是因为孩子在父母去世后(这是正确的说法吗?)不能再被收集吗?如果是这样,孩子会怎么样?它变成了僵尸,对吗?它会被init收集吗?即便如此,为什么它不在像僵尸一样结束之前打印出那一行呢


如果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;
}
#包括
int main(int argc,字符**argv){
printf(“这是来自父级%d的pid=%d的子级\n”、getpid()、getppid());
返回0;
}

顺便说一下,您在
printf

中缺少了一个
%d
,您肯定会得到两行

如果你没有,这可能是由于你如何运行程序。家长可能会打印并退出,如果此时您停止观看或收听,您将丢失来自孩子的消息

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

例如,这里是
/server的输出;回显“完成”

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

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.

当我尝试你的程序时,我收到数百条“等待:无子进程”的
错误消息。没关系,我给客户端程序的名称错误。当我修复它时,它按预期工作,我得到了两行输出。在exec()之后,程序不存在。exec在父级和子级中执行。循环永远不会循环(如果exec成功)@posixking。请接受我的回答。它不正确,我无法删除它。如果stdout连接到终端,它应该是行缓冲的,所以不需要刷新。所有的流在关闭时都会自动刷新,这是在程序结束时发生的。我只是想重新设计他的案子,但做不到。你说得对。删除…谢谢&我的错,你是对的。我在stackoverflow中键入了换行符,但忘了在程序中键入它。换行符也会刷新流,所以它现在可以工作了。@posixKing这不重要,因为返回将刷新。也许你只是因为两条信息在同一条线上而看不到?
user ~ $ ./server; echo "Done."
This is the child with pid = 27904 from parent
Done.
user ~ $ This is the child with pid = 27905 from parent
user ~ $ ./server | cat; echo "Done."
This is the child with pid = 27953 from parent
This is the child with pid = 27955 from parent
Done.