在Unix/Linux中用fork函数建立一个新的进程。进程是由当前已有进程调用fork函数建立,分叉的进程叫子进程,建立者叫父进程。该函数的特色是调用一次,返回两次,一次是在父进程,一次是在子进程。两次返回的区别是子进程的返回值为0,父进程的返回值是新子进程的ID。子进程与父进程继续并发运行。若是父进程继续建立更多的子进程,子进程之间是兄弟关系,一样子进程也能够建立本身的子进程,这样能够创建起定义关系的进程之间的一种层次关系。html
程序包含位于内存的多个组成部分,执行程序的过程将根据须要来访问这些内容,包括文本段(text segment)、数据段(data segments)、栈(stack)和堆(heap)。文本段中存放CPU所执行的命令,数据段存放进程操做的全部数据变量,栈存放自动变量和函数数据,堆存放动态内存分配状况数据。当进程被建立时,子进程收到父进程的数据副本,包括数据空间、堆、栈和进程描述符。linux
程序1:建立一个子进程,子进程对继承的数据进行修改,而后分别输出父子进程的信息。程序以下:面试
fork函数执行后程序结构图以下:服务器
子进程与父进程并行执行,所以在父进程中sleep(10),让子进程先执行,而后再执行父进程。并发
程序执行结果以下所示:函数
如何建立多个子进程呢?在开发并发服务器时,用到的进程池模型须要先建立指定书目的子进程。举个例子,假如咱们如今须要建立2个子进程,很容易想到的是调用一个循环,执行fork函数2次便可。尝试一下是否可行呢?代码以下:测试
程序执行结果以下:spa
从结果来看,子进程的数目不是2而是3,这是为何呢?先简单的分析一下:从结果看出父进程ID为10669,子进程的ID分别为:10670、1067一、10672。3d
父子进程之间的关系以下:code
ID为10670的子进程也调用fork函数,建立了一个进程。由于fork函数建立的进程是父进程的一份拷贝,保存了当前的数据空间、堆、栈及共享代码区域。正确的方式应该是在子进程中跳出,中止继续fork。改进的代码以下:
程序执行结果以下:
从结果能够看出这父进程(ID为10789)建立了两个子进程(ID分别为:10790、10791)。
现有有这样一个面试题,程序以下:
1 #include <stdio.h> 2 #include <unistd.h> 3 #include <stdlib.h> 4 #include <sys/types.h> 5 6 int main() 7 { 8 pid_t pid1; 9 pid_t pid2; 10 11 pid1 = fork(); 12 pid2 = fork(); 13 14 printf("pid1=%d,pid2=%d\n",pid1,pid2); 15 exit(0); 16 }
要求以下:
已知从这个程序执行到这个程序的全部进程结束这个时间段内,没有其它新进程执行。
一、请说出执行这个程序后,将一共运行几个进程。
二、若是其中一个进程的输出结果是“pid1:1001, pid2:1002”,写出其余进程的输出结果(不考虑进程执行顺序)。
这个题目考查fork函数的理解。fork的做用是复制一个与当前进程同样的进程。新进程的全部数据(变量、环境变量、程序计数器等)数值都和原进程一致,可是是一个全新的进程,并做为原进程的子进程,父子进程并行的执行剩下的部分。
程序的执行过程以下:
(1)程序开始执行时候系统分配一个进程进行执行,称该进程为主进程P,进程ID题目未给,
(2)主进程执行到第一个fork函数的时候,建立一个新的子进程P1,有题目可知进程ID为1001,fork函数有两个返回值,返回pid=0表明子进程P1,pid1>0表明父进程P。
(3)如今有两个进程P和P1,分别执行剩下部分,
(4)P进程(父进程,因此pid1=1001)调用fork建立子进程P2,返回两个值中pid2=1002表示P2的进程ID返回给父进程P,pid2=0子进程P2自己,因此输出pid1=1001, pid2=1002和pid1=1001,pid2=0。
(5)P1进程(子进程,因此pid1=0)调用fork建立子进程P3,进程ID类推为1003,返回两个值中pid2=1003表示P3的进程ID返回给父进程P1,pid2=0标识进程P3自己。因此输出pid1=0,pid2=1003和pid1=0,pid2=0。
(6)执行整个结束。
根据以上分析可知答案:
一、一共执行了四个进程。(P0, P1, P2, P3)
二、另外几个进程的输出分别为:
pid1:1001, pid2:0
pid1:0, pid2:1003
pid1:0, pid2:0
上机测试以下:
测试结果以下:
测试结果虽然不是1001,可是能够看出理论分析过程是正确的。
题目来自:http://www.cnblogs.com/leoo2sk/archive/2009/12/11/talk-about-fork-in-linux.html