题目
阅读下面的代码,显示终端会打印出几个 hello world?
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>int main()
{fork();fork();fork();printf("hello world\n");exit(0);
}
答案是多少呢?我们一起分析一下。
原理分析
关于 fork
fork() 函数会创建一个新的子进程。子进程得到与父进程用户级虚拟地址空间相同的一份副本,包括代码段数据段、堆、共享库、用户栈等。
fork 调用一次,返回两次:一次是返回到父进程。一次是返回到新创建的子进程。调用返回后,父进程和子进程各自继续执行后边的指令。
父进程和子进程并发独立运行,内核能够以任意方式交替执行它们的指令。
父进程和子进程有相同但是独立的地址空间。
父进程和子进程之间共享文件。即子进程会继承父进程所有打开的文件。
fork 嵌套分析
我们可以通过画图,来理解带有嵌套 fork 调用的程序。
为了方便看出是哪个 fork 执行,在图中用标号进行了标注。
第一个 fork 执行了 1 次。第二 fork 执行了 2 次,第三个 fork 执行了 4 次。最终有 8 个进程运行程序。
从而 printf 函数被调用了 8 次。
结果
根据以上分析可知,代码最终打印 8 次 hello world。
我们可以在 PC 上验证一下,编译、执行后的输出结果:
$ gcc fork.c
$ ./a.out
hello world
hello world
hello world
hello world
hello world
hello world
hello world
hello world
实际结果与分析相同。
看来 fork() 不仅要会用,还要理解其背后的原理,还有就是掌握分析问题的方法。
如此,才能在遇到的问题的时候,从容不迫。
加油~