请考虑以下代码段:
int main()
{
fork();
fork();
fork();
printf("Hello World\n");
}
我得到了输出:[ubuntu 12.04]
aashish@aashish-laptop:~$ ./a.out
Hello World
Hello World
Hello World
aashish@aashish-laptop:~$ Hello World <---------------------------
Hello World
Hello World
Hello World
Hello World
为什么&#34; Hello Word&#34;在流程执行结束后输出?
答案 0 :(得分:5)
简短的回答是,您正在创建多个进程,这些进程相互之间异步运行。答案如下:
在shell提示符下键入 ./ a.out 时,会创建一个运行程序的进程。我们称之为过程1。
进程1调用fork()。这将创建一个新的子进程,进程2,并且在第一次fork()调用之后,1和2都继续执行,继续执行第二次fork()调用。进程1创建子进程3,进程2创建子进程4.所有四个进程从第二个fork()之后继续进行到最后的fork()调用。流程1创建流程5;流程2创建流程6;流程3创建流程7;和流程4创建流程8。
请注意,这些流程编号是任意的:不能保证按顺序创建它们。
一旦第一个fork()被执行,异步就会发挥作用。系统不保证关于孩子安排父母。从理论上讲,孩子可以在父母继续之前跑完,父母可以在孩子获得任何资源之前完成。最可能的情况是位于中间位置:原始进程与其后代共享资源,因此所有进程同时运行。
最后一块拼图是因为shell正在等待进程1完成。 仅进程1. shell不知道(或关心)进程1是否已启动其他进程。因此,当Process 1完成时,shell会显示提示。事实上,进程1的一些后代还没有达到printf()语句。当他们到达那里时,shell已经显示了它的提示。
要进一步探讨此问题,您可能需要尝试将 fork()调用更改为 printf(“%d \ n”,fork()); 和/或者将 printf(“Hello World \ n”)更改为 printf(“你好,来自pid%d \ n”,getpid())
答案 1 :(得分:3)
第二个shell提示之后的“Hello World”输出来自分叉进程,而不是来自shell(你)发起的那个。
答案 2 :(得分:0)
那是因为你制作了1个fork(2),然后你再次分叉(4),然后再次(8)然后为每个fork打印Hello世界。这就是为什么你有8个输出。
答案 3 :(得分:0)
int main() {
pid_t c[3];
int i, n = 0;
for (i = 0; i < 3; ++i) {
switch ((c[n] = fork())) {
case 0: break;
case -1: perror("fork"); exit(EXIT_FAILURE);
default: ++n;
}
}
printf("[%d] Hello World\n", (int)getpid());
// Without waiting, some children may still be running when the
// parent exits. This makes it look like output is generated
// after the process is over, when in fact not all the processes
// are done yet.
//
// The process is not really finished until its children are
// finished. The wait call waits on a child process to finish.
for (i = 0; i < n; ++i) wait(0);
return 0;
}