操作系统概念Linux下用 C语言 fork()函数创建进程的实验及解释

这是我们操作系统课的一个实验

一、实验目的

  1. 加深对进程概念的理解,明确进程和程序的区别。进一步认识并发执行的实质。
  2. 认识进程生成的过程,学会使用fork生成子进程,并知道如何使子进程完成与父进程不同的工作。

二、实验要求

进行Linux(可选)下的创建进程实验并提供截图和源代码

三、实验准备

首先学习了一下fork()的用法和特点,这几点是要注意的:

1、进程可以看做程序的一次执行过程。在linux下,每个进程有唯一的PID标识进程。PID是一个从1到32768的正整数,其中1一般是特殊进程init,其它进程从2开始依次编号。当用完32768后,从2重新开始。
2、进程在linux中呈树状结构,init为根节点,其它进程均有父进程,某进程的父进程就是启动这个进程的进程,这个进程叫做父进程的子进程。
3、fork的作用是复制一个与当前进程一样的进程。新进程的所有数据(变量、环境变量、程序计数器等)数值都和原进程一致,但是是一个全新的进程,并作为原进程的子进程。

还有就是关于fork()的返回值,fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:

1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;

这不是我们课的代码,我为了更加容易理解做了修改,
主要是在最后一行多加了一句间接打印出当前进程状态的语句
这里的getpid()是获取当前进程的PID标识(这是唯一能确定该进程的标识符

四、实验结果

先来看这段代码

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>
int main(){
    int pid1 = fork();
    printf("**1**\n");
    int pid2 = fork();
    printf("**2**\n");
    if(pid1 == 0){
        int pid3 = fork();
        printf("**3**\n");
    }
    else 
        printf("**4**\n");
    printf("------this id: %d , pid1: %d , pid2: %d \n",getpid(),  pid1, pid2);
    return 0;
}

先把程序分成三个部分,分别对应三个printf * 的语句

结果直接贴出来,是这样的
这里写图片描述

很明显,一共创建了五个进程,PID分别为8420,8421,8422,8423,8424,8425
下面来分析一下它们具体的情况

对于8420

首先对最开始的主进程分析,由输出可以知道主进程的pid是8420,它执行了整个代码,所以由该进程输出的是
这里写图片描述
然后又由于8420创建了两个进程,第一个fork创建的进程的pid是8421
第二个fork创建的是8422,因为pid1的值为8421,所以没有进入if语句,也就没有第三个fork。

对于8421

它是有8420的第一个fork语句得到的,然后它复制了父进程的一切状态,并从创建该进程的fork语句开始执行代码(即第一个fork语句)

注意:虽然8421得到了父进程8420的pid1的值,但是由于第一个fork语句让8421的pid置为零,这是fork函数返回值的特性

这里写图片描述
然后在第二个fork语句创建了新进程8423
因为pid1为0,所以在进入第三个fork语句,创建了新进程8424

对于8422

它是有8420的第二个fork语句得到的,同理就得到了8420的pid1和pid2,但是因为pid2是创建该进程的fork返回值,所以pid2置为0
这里写图片描述
因为这个进程从第二个fork语句执行,所以第一个printf语句没有输出
因为pid1不是零所以也没有第三个fork语句,输出4就退出了

对于8423

它是有8421的第二个fork语句得到的
于是得到了8421的pid1和pid2
但是因为pid2是创建该进程的fork返回值,所以pid2置为0

这里写图片描述

因为这个进程从第二个fork语句执行,所以第一个printf语句没有输出
因为pid1为0,所以有第三个fork语句创建了一个新的进程8425并输出3

对于8424

它是有8421的第三个fork语句得到的
于是得到了8421的pid1和pid2,注意这时的pid2还不是零
这里写图片描述
因为这个进程从第三个fork语句执行,所以只有一个输出3

对于8425

它是有8423的第三个fork语句得到的
于是得到了8423的pid1和pid2,均为零
这里写图片描述
因为这个进程从第三个fork语句执行,所以也只有一个输出3

最后我们再来整理一些这些进程的关系

这里写图片描述
发现结果的输出也就是代表着进程的执行顺序是不定的,并不是父进程就一定比子进程快,应该是根据进程调度程序的控制决定的!

猜你喜欢

转载自blog.csdn.net/jankingmeaning/article/details/79967715