进程管理Word文件下载.docx
《进程管理Word文件下载.docx》由会员分享,可在线阅读,更多相关《进程管理Word文件下载.docx(20页珍藏版)》请在冰豆网上搜索。
![进程管理Word文件下载.docx](https://file1.bdocx.com/fileroot1/2022-11/23/8fbd4d67-48bd-420b-92d1-bca1c97c37bc/8fbd4d67-48bd-420b-92d1-bca1c97c37bc1.gif)
程序流程图如下页所示:
(3)详细设计
.主要算法思想:
系统为进程设置3种运行状态:
E--执行态;
R--高就绪态;
C--完成态。
运行态(Running):
当一个进程在处理机上运行时,则称该进程处于运行状态。
就绪态(Ready):
一个进程获得了除处理机外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。
阻塞态(Blocked):
(又称挂起状态、等待状态):
一个进程正在等待某一事件发生而暂时仃止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。
系统开始时,先初始化三个进程。
然后输出命令菜单,根据用户输入要求,调用功能,创建新进程,就是申请一个新的PCB,然后根据输入信息设置PCB的值,即可完成新进程的初始化。
此时判断可用PCB块数为多少,是否可以继续创建新进程,来实现进程的创建的工作。
显示当前的执行进程,先要判断当前的执行进程是什么,即判断当前所有PCB中STATUS为’E’的PCB为那个进程的,然后便可输出相应的进程信息。
换出进程实质上就是更改PCB内数据的值,删除当前执行进程,首先需要找到正在执行的进程,然后删除其PCB,然后寻找当前优先级最高的就绪状态,调为执行状态。
进程间通信实质上时实现进程间BOX结构内信息的交换,当一个进程发送信息后,该进程的BOX设置为可用状态,而接受信息的BOX设置为不可用状态。
显示所有进程信息,即为输出所有有效PCB内的信息。
(二)数据结构:
1.每个进程有一个进程控制块PCB:
struct{
charname;
//
intid;
//进程身份(即:
内部标识符,如:
0,1,2)
charstatus;
//进程状态,可为E、R和C;
intpriority;
//进程优先数;
intflags;
//用于标志此PCB是否可用:
//(USE表示PCB已创建orUNUSE表示PCB未创建)
}
pcb[MAX];
//PCB[i]的信息
信箱BOX,内容包括:
charcomer;
//信息发送者(sendmessage)
intinfo_num;
//发来得信息数(messages'
snumber)
intmutex;
//信箱同步信号量(USE表示信箱可使用orUNUSE表示信箱不可使用)
intboxflag;
//信箱存在否的标志
}
box[MAX];
//进程i的信箱
(三)重要的函数模块:
1.find()这是用来寻找优先级最高的进程的关键函数,即寻找就绪队列中,优先权最高的进程。
在删除,查看当前运行的程序中有很关键的作用,被函数intscheduler()所调用。
寻找到就绪队列中进程优先权最高的进程,就方便了scheduler()函数调用。
intfind()//~~~~~寻找优先权最高的进程~~~~~
{
intj;
//用于循环计数
intd,t;
d=0;
for(j=0;
j<
MAX;
j++)//*****判断是否存在高就绪进程****
{
if(pcb[j].flags==USE)
{
if(pcb[j].status=='
r'
)
if(pcb[j].priority>
d)
d=pcb[j].priority;
t=pcb[j].id;
return(t);
//返回应调为优先权最高的进程
}
2.intscheduler()这是建立在find()的基础上的函数,用来找到当前优先级最高的进程,并执行该进程。
将进程变为可执行态。
本函数主要实现的就是将就绪队列中该调为执行的进程设置为执行态。
利用FIND()函数找到就绪队列中优先权最高的进程将之与当前执行的进程优先权进行比较,若高于当前执行状态优先权,则更改执行进程为所找到的进程,否则执行进程不更改。
intscheduler()
intpd;
pd=find();
if(exe==NIL)//***若当前执行程序为无***
pcb[pd].status='
e'
;
//将状态变为执行态
exe=pd;
elseif(pcb[pd].priority>
pcb[exe].priority)//判断优先级高低
//若优先级高于当前执行程序
pcb[exe].status='
//将状态变为执行态
}
return(exe);
(四)其他所用函数及其作用
voidinit();
//初始化创建原语
初始化创建原语主要是在主要功能是先创建三个进程,以便指令一开始运行时不会发生找不到进程的现象。
主要是根据输入信息进行PCB初始化即可。
voidcreate();
//创建原语
创建进程原语主要是实现新进程的创建,当程序指令发出创建新进程的命令时,系统分配一个PCB用于创建新进程,然后根据输入数据,完成新PCB的初始化任务
voidanalyse();
//判断是否创建新进程
本函数主要是根据可用PCB个数计数器的值来判断是否可以继续创建行进程,因为PCB的数量一定,所以创建进程数量不能超出范围,若计数器值为0则程序不能继续创建新进程
voiddeleted();
//终止进程
本函数主要实现当前正在执行进程的删除任务,由于程序中声明了全局变量EXE用来指向当前正在执行的进程,所以可以根据EXE来找到当前正在执行的进程,然后删除此进程(让其所对应的PCB删除即可),然后调用函数来调就绪进程中的某一进程变为执行态。
voiddisplay();
//显示当前执行的进程
与删除进程相似,需要用到全局变量EXE来找到当前执行的进程,然后将其PCB中信息输出即可
voiddisplayall();
//显示所有进程状态
此函数主要是显示所有进程的信息,所以只要将所有可用PCB的信息输出即可。
voidinform();
//发送消息函数(进程通信)
进程间通信函数,实现两个进程之间的通信,根据所输入的发送信息进程名照到相应进程名,同理找到接受信息进程名,然后改变两个进程对应的BOX机构中的信息,即可实现通信。
发送信息的进程发送信息后要清空BOX以便接受别的进程发来的信息或初始化BOX,接受信息进程在接受信息后要设置BOX为不可用状态,防止其接受别的进程的信息,直到BOX中信息被使用或设置才将其BOX恢复为可用状态。
voidexchage();
//换出进程函数
本函数主要实现的是更换PCB中的内容,即新进程使用老进程的PCB,主要是根据更换进程名照到需要更换进程,然后根据输入信息,更换其PCB的内容。
即可完成进程的替换。
(五)宏定义和全局变量
#defineMAX10//最大进程数
#defineNIL-1//用于执行进程为空
#defineUSE0//可用
#defineUNUSE-1//不可用
intexe;
//执行进程指针,其值为进程标识数;
(1)本程序的运行结果的截屏:
(1)本程序一开始时是进行三个进程的初始化任务,根据提示输入信息即可实现进程PCB的初始化:
(2)输入完三个进程信息后,然后根据命令菜单,输入命令,选择实现向用功能。
如下图:
(3)实现1号功能调用:
(4)实现2号功能调用,显示当前执行进程信息:
(5)实现3号功能调用,换出某个进程信息:
(6)实现4号功能调用,杀死运行进程的信息:
(7)实现5号功能调用,进程之间的通信的信息,如下图所示:
(8)实现6号功能调用,显示所有进程信息:
(9)实现7号功能调用,退出系统:
4、实验总结
本实验作为操作系统的课程设计实验,还是具有相当难度的,按照报告的提示和要求,利用指针链表等操作效果更好,但我们利用数组方法来实现相应功能。
关于进程间通信的实现,我们对相关知识掌握不够熟练,所以此处只是简单的利用BOX结构体实现对于通信的模拟。
本实验的测试结果表明,我们所编写的程序基本满足要求。
通过本次实验,我们加深了对进程概念及进程管理各部分内容的理解;
熟悉了进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构、通讯机构的实施;
对进程的调度、执行、阻塞、就绪也有了更进一步的了解;
对进程的调度算法及动态改变优先数有了更深的认识。
一个较大的程序通常都由若干个程序段组成,程序在执行时,各程序段必须按照先后次序逐个执行。
进程的三个基本状态:
一个进程正在等待某一事件发生而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。
关于进程通信,我们根据自己的理解建立了邮箱,以便于进程与邮箱,进程与进程之间的数据交换。
我们所使用的就是间接的通信方式,即通过邮箱来实现进程之间的数据交换。
在间接通信情况,消息不直接从发送者发送到接收者,而是发送到暂存消息的共享数据结构组成的队列,这个实体称为信箱(mailbox).因此二个进程通信情况,一个进程发送一个消息到某个信箱,而另一个进程从信箱中摘取消息。
间接通信的使用好处是增加了使用消息的灵活性。
发送者和接收者的关系可能是一对一、多对一,一对多或多对多。
一对一的关系允许一个专用通信链路用于二个进程间的交互,它能使俩进程间交互不受其它进程错误干予的影响,多对一的关系对客户/服务器交互特别有用,一个进程对多个其它进程(用户)提供服务。
在这种情况信箱经常称作为端口(port)。
一对多关系允许一个发送进程和多个接收进程交互,这可用来将消息广播(broadcast)给一组进程。
5、附录
程序的源代码为:
#include<
stdio.h>
iostream.h>
stdlib.h>
struct{
intscheduler();
//寻找该调为执行进程的进程,并使之执行
intfind();
//寻找就绪队列中,优先权最高的进程
intcount[MAX+1];
//可用PCB索引:
//其中:
count[0..MAX-1]分别标识pcb[0..MAX-1](1为存在,0反之)
//count[MAX]为还可创建的PCB个数
voidinit()//初始化创建原语
{intn;
charp;
for(intj=0;
3;
j++)
pcb[j].id=j;
//给进程身份(如:
1,2,3...)赋值
pcb[j].status='
//进程状态
printf("
\n请输入进程%d的名称和优先权:
"
j);
//***输入各进程优先级***
cin>
>
p>
n;
pcb[j].name=p;
pcb[j].priority=n;
//***
pcb[j].flags=USE;
//标识PCB已创建
count[j]=1;
//***修改'
可用PCB索引'
***
box[j].mutex=USE;
//信箱可使用
box[j].boxflag=USE;
for(j=3;
j<
j++)//********给不存在的PCB,BOX及未用对应PCB索引赋值*********
c'
pcb[j].flags=UNUSE;
box[j].boxflag=UNUSE;
count[j]=0;
count[MAX]=MAX-3;
//还可以创建的PCB个数
//创建原语
voidcreate()
intrep;
charp;
intpri;
for(intj=0;
j++)
if(count[j]==0)//寻找可以存放进程信息的PCB
rep=j;
break;
pcb[rep].id=rep;
pcb[rep].status='
//进程状态(可为E、R、T、W和C)
进程%d的名称和优先权为:
rep);
pri;
pcb[rep].name=p;
pcb[rep].priority=pri;
pcb[rep].flags=USE;
box[rep].boxflag=USE;
count[rep]=1;
count[MAX]--;
//当前还可用的pcb个数
//创建新的进程
voidanalyse()
charanswer;
//用于记录"
外存是否还有作业需创建进程"
的响应
\n是否要建立新进程?
(Y/N)"
);
TRY:
cin>
answer;
//取得响应值
if(answer=='
y'
||answer=='
Y'
create();
elseif(answer=='
n'
N'
return;
else
\n输入错误,请重新输入!
gotoTRY;
intt=0;
//用于寻找可用PCB数量
j++)//*****寻找可用PCB数量*****
if(pcb[j].flags==UNUSE)
t++;
}//*****************
if(t!
=0)
\n是否继续创建进程(Y/N):
//显示当前执行的进程
voiddisplay()
intn;
printf("
当前执行的进程为:
\n"
n=scheduler();
进程名:
%c"
pcb[n].name);
//终止当前执行的进程
voiddeleted()
intn;
n=scheduler();
pcb[n].status='
pcb[n].flags=UNUSE;
//撤消PCB
box[n].boxflag=UNUSE;
exe=NIL;
进程%c已被删除!
count[MAX]++;
voiddisplayall()
if(pcb[j].flags==USE)
进程%c状态为:
%c\n"
pcb[j].name,pcb[j].status);
应先权为:
%d\n"
pcb[j].priority);
//进程通信
voidinform()
charrequire;
\t是否确定发送信息(Y/N):
TRY:
require;
if(require=='
||require=='
)//*********答案***********
chargeter,fa;
intg,f;
intnumber;
\t\t请输入发送信息进程名:
fa;
\t\t请输入接收信息进程名:
geter;
\t\t输入所要发送信息数:
number;
for(intmi=0;
mi<
mi++)//***^^^发送消息^^^***
if(pcb[mi].name==geter)
g=pcb[mi].id;
//进程身份
for(intmm=0;
mm<
mm++)//***^^^发送消息^^^***
if(pcb[mm].name==fa)
f=pcb[mm].id;
if(box[g].boxflag==USE)
//*****判断信箱是否为空*****
if(box[g].mutex==USE)//USE表示信箱可使用orUNUSE表示信箱不可使用
box[g].mutex=UNUSE;
box[g].info_num=number;
box[g].comer=pcb[mm].name;
\t\t通信成功!
!
\t已接收到进程%c消息,消息数目是%d.\n"
fa,box[g].info_num);
box[f].mutex=USE;
//清空信箱
else//否,失败
\t\t通信失败!
请继续!
elseif(require=='
)//**********答案************
else//**********答案************
\n输入错误,请重新输入!
voidexchage()
charn,t;
inth;
请输入要替换的进程名:
请输入新进程名:
t;
cout<
<
请输入新增进程的优先权"
endl;
h;
for(intm=0;
m<
m++)
if(pcb[m].name==n)
pcb[m].priority=h;
pcb[m].name=t;
进程已成功替换!
//更改当前的执行进程
intscheduler()
voidmain()
inta;
init();
*************************************\n"
欢迎使用进程模拟管理器!
1)创建新进程2)查看运行进程\