linux下fork的运行机制

来源:互联网 发布:hp128fn网络打印设置 编辑:程序博客网 时间:2024/05/01 22:11

<!--@page { margin: 2cm }P { margin-bottom: 0.21cm }-->

如下C程序,在linux下使用gcc编译:
1#include"stdio.h"
2#include"sys/types.h"
3#include"unistd.h"
intmain()
4{
5   pid_t pid1;
6   pid_t pid2;
7   pid1 = fork();
8   pid2 = fork();
10   printf("pid1:%d,pid2:%d/n",pid1, pid2);
11}
     
要求如下:
     
已知从这个程序执行到这个程序的所有进程结束这个时间段内,没有其它新进程执行。
     1
、请说出执行这个程序后,将一共运行几个进程。
     2
、如果其中一个进程的输出结果是“pid1:1001,pid2:1002”,写出其他进程的输出结果(不考虑进程执行顺序)。
    
学习linuxfork的运行机制
预备知识
    1
、进程可以看做程序的一次执行过程。在linux下,每个进程有唯一的PID标识进程。PID是一个从132768的正整数,其中1一般是特殊进程init,其它进程从2开始依次编号。当用完32768后,从2重新开始。
     2
linux中有一个叫进程表的结构用来存储当前正在运行的进程。可以使用“psaux”命令查看所有正在运行的进程。
    3
、进程在linux中呈树状结构,init为根节点,其它进程均有父进程,某进程的父进程就是启动这个进程的进程,这个进程叫做父进程的子进程。
    4
fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。
解题的关键
     
有了上面的预备知识,我们再来看看解题的关键。我认为,解题的关键就是要认识到fork将程序切成两段。看下图:



     上图表示一个含有fork的程序,而fork语句可以看成将程序切为AB两个部分。然后整个程序会如下运行:

      step1、设由shell直接执行程序,生成了进程PP执行完Part.A的所有代码。

      step2、当执行到pid= fork();时,P启动一个进程QQP的子进程,和P是同一个程序的进程。Q继承P的所有变量、环境变量、程序计数器的当前值。

      step3、在P进程中,fork()QPID返回给变量pid,并继续执行Part.B的代码。

      step4、在进程Q中,将0赋给pid,并继续执行Part.B的代码。

      这里有三个点非常关键:

      1P执行了所有程序,而Q只执行了Part.B,即fork()后面的程序。(这是因为Q继承了PPC-程序计数器)

     2Q继承了fork()语句执行时当前的环境,而不是程序的初始环境。

     3Pfork()语句启动子进程Q,并将QPID返回,而Q中的fork()语句不启动新进程,仅将0返回。

解题


      下面利用上文阐述的知识进行解题。这里我把两个问题放在一起进行分析。

     1、从shell中执行此程序,启动了一个进程,我们设这个进程为P0,设其PIDXXX(解题过程不需知道其PID)。

      2、当执行到pid1= fork();时,P0启动一个子进程P1,由题目知P1PID1001。我们暂且不管P1

      3P0中的fork返回1001pid1,继续执行到pid2= fork();,此时启动另一个新进程,设为P2,由题目知P2PID1002。同样暂且不管P2

     4P0中的第二个fork返回1002pid2,继续执行完后续程序,结束。所以,P0的结果为“pid1:1001,pid2:1002”

     5、再看P2P2生成时,P0pid1=1001,所以P2pid1继承P01001,而作为子进程pid2=0P2从第二个fork后开始执行,结束后输出“pid1:1001,pid2:0”

     6、接着看P1P1中第一条fork返回0pid1,然后接着执行后面的语句。而后面接着的语句是pid2= fork();执行到这里,P1又产生了一个新进程,设为P3。先不管P3

     7P1中第二条forkP3PID返回给pid2,由预备知识知P3PID1003,所以P1pid2=1003P1继续执行后续程序,结束,输出“pid1:0,pid2:1003”

     8P3作为P1的子进程,继承P1pid1=0,并且第二条fork0返回给pid2,所以P3最后输出“pid1:0,pid2:0”

      9、至此,整个执行过程完毕。

      所得答案:

      1、一共执行了四个进程。(P0,P1, P2, P3

      2、另外几个进程的输出分别为:

      pid1:1001,pid2:0

      pid1:0,pid2:1003

      pid1:0,pid2:0

      进一步可以给出一个以P0为根的进程树:



 

原创粉丝点击