实验一 进程管理

  • 格式:docx
  • 大小:2.36 MB
  • 文档页数:6

操作系统原理实验

1 实验一 进程管理

一、实验目的

 加深对进程概念的理解,明确进程和程序的区别。

 进一步认识并发执行的实质。

 分析进程争用资源的现象,学习解决进程互斥的方法。

二、实验内容

1进程创建

编写一段程序,利用系统调用fork( )创建两个进程。当此程序运行时,在系统中有一个父进程和两个子进程活动。让每一个进程在屏幕上显示一个字符:父进程显示字符“a”;子进程分别显示字符“b”和字符“c”。

2进程控制

修改已经编好的程序,将每个进程输出一个字符改为每个进程输出一句话,在观察程序执行时屏幕上出现的现象,并分析原因。

如果在程序中使用系统调用lockf()来给每一个进程加锁,可以实现进程之间的互斥,观察并分析出现的现象。

背景知识

1、fork()

创建一个新进程

int fork()

其中返回int取值意义如下:

0:创建子进程,从子进程返回的id值

大于0:从父进程返回的子进程id值 操作系统原理实验

2 -1:创建失败

2、lockf(files,function,size):

用作锁定文件的某些段或者整个文件,本函数适用的头文件为:

#include

参数定义:

int lockf(files,function,size)

int files,function;

long size;

其中:files是文件描述符:function是锁定和解锁;1表示锁定,0表示解锁。size是锁定和解锁的字节数,若用0,表示从文件的当前位置到文件尾。

三、实验步骤

1. 运行Linux-Ubuntu虚拟机,运行终端

2. 使用vim 编写参考程序一,后缀名为 .c ,退出并保存于home目录下。使用ll 语句查看文件信息。

3. 使用“ gcc 文件名 -o 编译后新文件名 ”语句进行编译。eg: gcc hello.c -o hello

4. 编译成功,输出“ ./编译后新文件名 ”语句运行语句。 eg: ./hello

5. 运行成功,将在终端打印出bac,acb或bca。

6. 同2~5步骤运行程序二和三。

四、程序清单

a. #include

main()

{

int p1,p2; //定义一个p1,p2变量

while ((p1=fork())= =-1);

if (p1= =0)

putchar(‘b’);

else

{

while ((p2=fork()= =-1);

if (p2= =0)

Putchar(‘c’);

else

putchar(‘a’); 操作系统原理实验

3 }

}

分析:从进程并发执行来看,输出bac,acb或bca都有可能。

原因:fork()创建进程所需要的时间要多于输出一个字符的时间,因此在主进程创建进程2的同时,进程1就输出了”b”,而进程2和主程序的输出次序是有随机性的,所以会出现多种可能结果。

b. 进程控制源程序:

#include

main()

{

int p1,p2,i;

while ((p1=fork()= =-1);

if (p1= =0)

for(i=0;i<50;i++)

printf(“child%d\n”,i);

else

{

while ((p2=fork()= =-1);

if (p2= =0)

for(i=0;i<50;i++)

printf(“son%d\n”,i);

else

for(i=0;i<50;i++)

printf(“daughter%d\n”,i);

}

}

运行结果:

Child…

Son…

Daughter…

或child

…son

…child

…son

…daughter

分析:由于函数printf()输出的字符串之间不会被中断,因此,字符串内部的字符顺序输出时不变。但是,由于进程并发执行时的调度顺序和父子进程的抢占处理机问题,处处字符串的顺序和先后随着执行的不同而发生变化。

c. 参考程序3:

#include

#include

main()

{

int p1,p2,i; 操作系统原理实验

4 while ((p1=fork()= =-1);

if (p1= =0)

{

lockf(1,1,0);

for(i=0;i<50;i++)

printf(“child%d\n”,i);

lockf(1,0,0);

}

else

{

while ((p2=fork()= =-1);

if (p2= =0)

{

lockf(1,1,0);

for(i=0;i<50;i++)

printf(‘son%d\n”,i);

lockf(1,0,0);

}

else

{

lockf(1,1,0);

for(i=0;i<50;i++)

printf(“daughter%d\n”,i);

lockf(1,0,0);

}

}

}

五、测试结果

程序一: 操作系统原理实验

5

程序二:

程序三:

操作系统原理实验

6

六、总结

通过本次实验,我更加了解进程的概念。进程是动态的,程序是静态的。进程是一个状态变化过程。同时也复习了linux 系统的基本命令。

在编写进程控制程序的过程中,头文件中缺少头文件 #include 报错,却找不到原因。

“子进程”和“父进程”的概念比较难理解。fork()函数用于从一个已经存在的进程内创建一个新的进程,新的进程称为“子进程”,相应地称创建子进程的进程为“父进程”。使用fork()函数得到的子进程是父进程的复制品,子进程完全复制了父进程的资源。进程之间是相互独立的,fork()创建的父子进程,都包含有fork()函数执行之前的所有变量。