华佗养生网
您的当前位置:首页操作系统实验二

操作系统实验二

来源:华佗养生网


.

.

操作系统实验

实验二 进程管理

学 号 1215108019 姓 名 克帆 学 院 信息学院 班 级 12电子2

.

实验目的

1、理解进程的概念,明确进程和程序的区别。 2、理解并发执行的实质。

3、掌握进程的创建、睡眠、撤销等进程控制方法。

实验容与要求

基本要求:用C语言编写程序,模拟实现创建新的进程;查看运行进程;换出某个进程;杀死进程等功能。

实验报告容

1、进程、进程控制块等的基本原理。

进程是现代操作系统中的一个最基本也是最重要的概念,掌握这个概念对于理解操作系统实质,分析、设计操作系统都有其非常重要的意义。为了强调进程的并发性和动态性,可以给进程作如下定义:进程是可并发执行的程序在一个数据集合上的运行过程,是系统进行资源分配和调度的一个单位。

进程又就绪、执行、阻塞三种基本状态,三者的变迁图如下:

就绪

I/O完成 时间片完 进程调度 I/O请求

阻塞 执行 由于多个程序并发执行,各程序需要轮流使用CPU,当某程序不在CPU上运行时,必须保留其被中断的程序的现场,包括:断点地址、程序状态字、通用寄存器的容、堆栈容、程序当前状态、程序的大小、运行时间等信息,以便程序再次获得CPU时,能够正确执行。为了保存这些容,需要建立—个专用数据结构,我们称这个数据结构为进程控制块PCB (Process Control Block)。

进程控制块是进程存在的惟一标志,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。当创建一个进程时,实际上就是为其建立一个进程控制块。

在通常的操作系统中,PCB应包含如下一些信息:

① 进程标识信息。为了标识系统中的各个进程,每个进程必须有惟一的标识名或标

识数。

.

.

② 位置信息。指出进程的程序和数据部分在存或外存中的物理位置。

③ 状态信息。指出进程当前所处的状态,作为进程调度、分配CPU的依据。 ④ 进程的优先级。一般根据进程的轻重缓急其它信息。 这里给出的只是一般操作系统中PCB所应具有的容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。

程度为进程指定一个优先级,优先级用优先数表示。

⑤ 进程现场保护区。当进程状态变化时(例如一个进程放弃使用CPU),它需要将当时的CPU现场保护到存中,以便再次占用CPU时恢复正常运行,有的系统把要保护的CPU现场放在进程的工作区中,而PCB中仅给出CPU现场保护区起始地址。

⑥ 资源清单。每个进程在运行时,除了需要存外,还需要其它资源,如I/O设备、外存、数据区等。这一部分指出资源需求、分配和控制信息。

⑦ 队列指针或字。它用于将处于同一状态的进程成一个队列,在该单元中存放下一进程PCB首址。

⑧其它信息。

这里给出的只是一般操作系统中PCB所应具有的容,不同操作系统的PCB结构是不同的,我们将在2.8节介绍Linux系统的PCB结构。

2、 程序流程图。

功能选择(输入1~6) 开始 1 create 创建新进程 2 Run 查看运行的进程 3 Huanchu 换出进程 4 Kill 杀死进程 5 Huanxing 唤醒进程 6 Viewall 查看内存的状态 7 Exit(0) 结束进程模拟程序 操作结束 .

.

3、程序及注释。

#include #include #include

struct jincheng_type{ // 定义表示进程信息的结构体 出 };

struct jincheng_type neicun[20]; 标志位

void create() //函数--创建一个新进程 { 用 元

scanf(\"%d\",&(neicun[i].pid)); for(int j=0;jif(neicun[i].pid==neicun[j].pid) {

printf(\"\\n该进程已存在\\n\"); return;

//当输入的新进程与原有进程ID

printf(\"\\n请输入新进程pid\\n\");

//输入新进程ID存至选出的存单

if(shumu>=20) printf(\"\\n存已满,请先换出或杀死进程\\n\"); else{

for(int i=0;i<20;i++)

if(neicun[i].zhuangtai==0) break;

//选出空着的存单元给新进程使

//判断存空间是否已满

//定义20个存单位给进程使用

int shumu=0,guaqi=0,pid,flag=0; //定义正在执行进程数目,被挂起进程数目,进程ID,运行

int info;

//容

int pid;

//进程ID

//大小

//进程的状态,这里用0表示没有建立或被杀死,1表示执行,2表示换

int youxian; //优先级 int daxiao; int zhuangtai;

相同时,显示\"该进程已存在\"

.

.

}

}

}

//输入新进程的优先级、大小和容

printf(\"\\n请输入新进程优先级\\n\"); scanf(\"%d\",&(neicun[i].youxian)); printf(\"\\n请输入新进程大小\\n\"); scanf(\"%d\",&(neicun[i].daxiao)); printf(\"\\n请输入新进程容\\n\"); scanf(\"%s\",&(neicun[i].info)); neicun[i].zhuangtai=1; shumu++;

//将新进程的存单元状态//正在运行的进程数目加一

(zhuangtai)设成\"1\",以表示存在且未被换出

void run() 程 { }

//函数--查看正在运行的进

for(int i=0;i<20;i++) { } if(!flag)

printf(\"\\n当前没有运行进程\\n\");

//若当前没有运行进程(即

if(neicun[i].zhuangtai==1) { }

printf(\"\\n pid=%d--\",neicun[i].pid); printf(\"youxian=%d--\",neicun[i].youxian); printf(\"daxiao=%d--\",neicun[i].daxiao); printf(\"zhuangtai=%d--\",neicun[i].zhuangtai); printf(\"info=%c\",neicun[i].info); flag=1;

//将存在且未被挂起(即

zhuangtai=1)的进程显示出来,若存在这样的程序,则将flag设成1

flag=0),则显示\"当前没有运行进程\"

void huanchu() {

if(!shumu) {

//函数--换出进程 //判断是否无进程存在

printf(\"\\n当前没有进程存在\\n\"); return;

.

.

}

}

//输入需要换出的进程ID,

printf(\"\\n 输入唤出进程ID值\"); scanf(\"%d\",&pid); for(int i=0;i<20;i++) { } if(!flag)

if(pid==neicun[i].pid) { }

if(neicun[i].zhuangtai==1) { }

neicun[i].zhuangtai=2; guaqi++;

//若该ID代表的进程正在运行,则

将其挂起,即将zhuangyai置成2,并将guaqi加一

printf(\"\\n已经成功换出进程\\n\");

else if(neicun[i].zhuangtai==2) flag=1; break;

printf(\"\\n要唤出的进程已被挂起\\n\");

//若该ID代表的进程已被挂起,即zhuangtai==2,则显示'要唤出的进程已被挂起'

printf(\"\\n要唤出的进程不存在\\n\"); //若进程不存在,给出显示

void kill() {

if(!shumu) { }

//函数--杀死进程 //判断是否无进程存在

printf(\"\\n当前没有进程存在\\n\"); return;

//读入要杀死的进程ID

printf(\"\\n 输入杀死进程的ID值\"); scanf(\"%d\",&pid); for(int i=0;i<20;i++) {

if(pid==neicun[i].pid) {

//若进程正在运行则再次询问是

if(neicun[i].zhuangtai==1) {

否要杀死,通过用户的反馈执行不同操作

printf(\"\\n该进程正在运行,确定要杀死吗?\\n\"); printf(\"\\n请输入 1:Yes;0:NO \\n\"); scanf(\"%d\",&flag);

.

.

if(flag) { }

//将zhuangtai置为0,表示进程被

neicun[i].zhuangtai=0; shumu--;

杀死,并将shumu自减一

printf(\"\\n已经成功杀死进程\\n\");

printf(\"\\要杀死的进程正在运行\\n\");

else

}

else if(neicun[i].zhuangtai==2)

接杀死

{ neicun[i].zhuangtai=0; shumu--;

printf(\"\\n已经成功杀死进程\\n\");

} flag=1; break;

}

}

if(flag==0) printf(\"\\n要杀死的进程不存在\\n\"); }

void huanxing() { if(!shumu)

{ printf(\"\\n当前没有运行进程\\n\"); return;

}

if(!guaqi)

{ printf(\"\\n当前没有挂起进程\\n\"); return;

}

printf(\"\\n输入pid\\n\");

scanf(\"%d\",&pid); for(int i=0;i<20;i++) { if(pid==neicun[i].pid) {

flag=false;

.

//若该进程已经被挂起,则直

//若进程不存在,给出显示

//函数--唤醒进程

//判断是否无进程存在

//判断是否无进程被挂起

//输入需要唤醒进程ID

.

}

}

}

if(neicun[i].zhuangtai==2) { }

neicun[i].zhuangtai=1; guaqi--;

//判断该进程是否被挂起,若没有则将

其唤醒并将guaqi自减一

printf(\"\\n已经成功唤醒进程\\n\");

else if(neicun[i].zhuangtai==2) flag=1; break;

printf(\"\\n要唤醒的进程已被挂起\\n\");

//若目标进程已被挂起,则显示'要唤醒的进程已被挂起'

if(!flag) printf(\"\\n要唤醒的进程不存在\\n\"); //若要唤醒的进程不存在,给出显示

void viewall() { }

void main() {

int n=1; int num;

//函数--查看存状态

for(int i=0;i<20;i++) //显示所有20个存单元的状态 { }

printf(\"\\n pid=%d\",neicun[i].pid); printf(\"youxian=%d\",neicun[i].youxian); printf(\"daxiao=%d\",neicun[i].daxiao); printf(\"zhuangtai=%d\",neicun[i].zhuangtai); printf(\"info=%c\",neicun[i].info);

//主函数

for(int i=0;i<20;i++) {

while(n)

//先将存zhuangtai位清零

neicun[i].zhuangtai=0;

printf(\"\\n fff \\n\"); printf(\"\\n printf(\"\\n printf(\"\\n printf(\"\\n printf(\"\\n

1.创建新的进程 \\n\"); 2.查看运行进程

\\n\");

\\n\");

3.唤出某个进程

printf(\"\\n*************************************************\\n\");

4.杀死某个进程 \\n\"); 5.唤醒某个进程 \\n\");

.

.

}

}

printf(\"\\n 6.查看存状态 \\n\");

printf(\"\\n 7.退出进程 \\n\");

printf(\"\\n*************************************************\\n\"); printf(\"\\n请选择(1-7)\\n\"); scanf(\"%d\",&num); switch(num) {

case 1:create();break; case 2:run();break; case 3:huanchu();break; case 4:kill();break; case 5:huanxing();break; case 6:viewall();break; case 7:exit(0); default:n=0; } flag=0;

//功能选择

4、程序运行演示与截图

(1)创建新进程,依次建立进程1、2、3,图中为建立进程2。

.

.

(2)查看运行的进程与查看存状态

(2)换出进程。图中以换出进程3为例。

(4)此时再次查看运行的进程与查看存状态,可以看到进程3已不在运行的进

.

.

程中,存状态中其zhuangtai标识等于2,表明进程3确实已被换出。

.

.

(5)唤醒进程。图为将进程3唤醒。

.

.

(6)此时再次查看运行的进程与查看存状态,可以看到进程3重新出现在运行的进程中,且存状态中其zhuangtai标识等于1,表明进程3已被成功唤醒。

(7)杀死进程。图中以杀死进程3为例,并附以杀死后运行的进程与存状态图,存状态中进程3的zhuangtai=0,表示进程3已被杀死。

.

.

.

.

5、 实验结论

通过这次实验,我了解到进程控制块在进程管理中的重要作用,它跟踪程序执行的情况,表明了进程在当前时刻的状态以及与其它进程和资源的关系。同时也明白了我们平常使用程序的工作原理。

.

因篇幅问题不能全部显示,请点此查看更多更全内容