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

原创 2018年04月16日 22:26:22

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

一、实验目的

  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

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

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

操作系统实验,进程控制

  • 2011年04月03日 13:40
  • 249KB
  • 下载

Linux下C语言开发(进程控制编程——fork()、exec函数族)

在Linux中创建一个新进程的唯一方法是使用fork()函数。fork()函数是Linux中一个非常重要的函数,和以往遇到的函数有一些区别,因为fork()函数看起来执行一次却返回两个值。...
  • Thanksgining
  • Thanksgining
  • 2014-12-15 15:00:19
  • 4549

linux c之创建进程fork和vfork函数之间的区别

1、函数简介       1)、得到当前的进程id pid_t getpid();       2)、fork函数          要创建进程,必须调用fork函数, 系统调用for...
  • u011068702
  • u011068702
  • 2017-01-12 20:36:32
  • 594

操作系统fork函数解析

首先看下fork的基本知识:     函数原型:pid_t fork( void);           返回值: 若成功调用一次则返回两个值,子进程返回0,父进程返回子进程ID;否则,出错返回-...
  • piaocoder
  • piaocoder
  • 2016-05-06 22:51:02
  • 1363

操作系统实验一之进程的创建实验

一、题目 运行程序,解释现象 void main(){ int pid1=fork(); printf(“**1**\n”); int pid2=fork(); printf(...
  • Kiloveyousmile
  • Kiloveyousmile
  • 2017-04-08 12:06:52
  • 879

Linux创建进程的fork()函数

今天总结一下Linux的进程创建,以及需要的系统调用的fork函数,记录一下,作为一个心得吧。         在Linux中,fork函数的功能就是在一个进程中创建一个新的进程,当前调用fork函数...
  • u010727765
  • u010727765
  • 2016-06-30 23:49:22
  • 953

生产者与消费者 进程的同步与互斥模拟

  • 2009年01月07日 20:42
  • 312KB
  • 下载

进程系统调用——fork函数深入理解

原创作品 转载请注明出处http://blog.csdn.net/always2015/article/details/45008785当我们在一个现代系统上运行一个程序的时候,我们会得到一个假象,...
  • Always2015
  • Always2015
  • 2015-04-12 11:53:38
  • 3012

操作系统(Linux)---fork()函数解析与进程

编制一段程序,使用系统调用fork( )创建两个子进程,这样在此程序运行时,在系统中就有一个父进程和两个子进程在活动。每一个进程在屏幕上显示一个字符,其中父进程显示字符A,子进程分别显示字符 B和字符...
  • qq_23948283
  • qq_23948283
  • 2016-09-24 11:55:03
  • 1312

Linux下fork创建进程的一些思考

1. 进程的概念在多道程序环境下,允许多个程序并发执行,此时它们将失去封闭性,并具有间断性及不可再现性的特征。为此引入了进程(Process)的概念,以便更好地描述和控制程序的并发执行,实现操作系统的...
  • Gpwner
  • Gpwner
  • 2016-12-22 13:52:04
  • 1105
收藏助手
不良信息举报
您举报文章:操作系统概念Linux下用 C语言 fork()函数创建进程的实验及解释
举报原因:
原因补充:

(最多只允许输入30个字)