一个进程执行下列语句:
for(i=0; i<n; i++) fork();
问:该进程创建了多少个子进程,该语句执行结束后,该进程有多少个子孙进程。
解答:
分析1:显然,A进程创建了n个子进程。那么,该语句执行结束后,A进程会有多少个子孙进程呢?我们把这条语句改为下列语句后进行分析:
for(i=n; i>0; i--) fork();
该语句的循环体执行的次数与原语句是一样的。
当n=0时,没有子进程被创建,0=2^0-1;
当n=1时,创建了一个子进程,1=2^1-1;
当n=2时,A进程创建了2个子进程,第1个子进程的i从n-1=1开始执行该循环语句;第2个子进程的i从n-2=0开始执行该循环语句。所以A的子孙进程共有2+(2^1-1)+0=2^2-1;
当n=3时,A进程创建了3个子进程,第1个子进程的i从n-1=2开始执行该循环语句;第2个子进程的i从n-2=1开始执行该循环语句;第3个子进程的i从n-3=0开始执行该循环语句。所以A的子孙进程共有3+(2^2-1)+(2^1-1)+0 = 2^3-1;
……
所以,得出该循环语句执行结束后,A进程的子孙进程共有2^n-1个。
分析2:循环语句for(i=0; i<n; i++) fork()创建的子孙进程数用f(n)表示,而该语句创建的子孙进程数相当于下列语句创建的进程数的2倍加1。
for(i=1; i<n; i++) fork();
即f(n)=2f(n-1)+1
而f(0)=0,f(1)=1;
得出递推公式:
f(n)=2f(n-1)+1 (n>1)
f(1)=1
利用组合数学中的方法求解该方程得出f(n)=2^n-1
下面用程序验证。假设n=3,即执行语句 for(i=0; i<3; i++) fork();后A有多少个子孙进程。从上面的分析可知,A进程有3个子进程,其中一个子进程可以创建3个子孙进程,一个子进程可以创建1个子进程,还有一个子进程没有创建子进程,A进程共7个子进程。
源程序如下:
#include <stdio.h>
#include <unistd.h>
int main()
{
int i;
for(i=0; i<3; i++) fork();
printf("fork\t");
getchar();
return 0;
}
运行这个程序,观察进程情况,可知与上面分析的结果一样。
程序运行结果截图如下:
观察到的进程情况如下,系统中共有8个进程,14543是题目中所描述的A进程,14544、14545、14546是A的3个子进程,14547、14548是A的第一个子进程的子进程,14549是A的第二个子进程的子进程,14550是A的第一个子进程的孙进程。