进程管理.docx
- 文档编号:25860850
- 上传时间:2023-06-16
- 格式:DOCX
- 页数:25
- 大小:429.22KB
进程管理.docx
《进程管理.docx》由会员分享,可在线阅读,更多相关《进程管理.docx(25页珍藏版)》请在冰豆网上搜索。
进程管理
操作系统功能模拟设计实验
课程名称:
操作系统原理
题目:
进程管理
系别:
计算机科学与技术系
专业:
网络工程
年级:
2011级
学生:
学号:
11040320
指导教师:
谢雪胜
完成日期:
2013年12月18日
一、实验目的
本实验主要掌握进程的基本概念、进程的控制,包括进程的新建、换出,以及进程之间的通信等问题。
二、实验内容
本程序至少要有:
创建一个进程;查看运行进程;换出某个进程、杀死运行进程以及进程之间通信等功能。
3、实验环境
基于windows系统,使用C++语言进行编写
四、实验主要步骤
1、任务分析:
本次实验的题目为:
进程管理——进程管理模拟系统,对本实验的分析要求是:
(1)根据用户的需求来创建n个进程(n为即满足用户需求,又不超出系统可容的最大进程数);
(2)使用静态优先数,在进程创建时给与其优先权;
(3)可显示当前正在执行的进程,也可以显示所有未删除的进程信息
进程间能实现通信操作;
(4)删除当前执行进程,调取另一个进程作为当前的执行进程;
(5)换出就绪状态中的某一进程;
综上所述,本实验旨在:
(1)深进程概念及进程管理各部分内容的理解;
(2)熟悉进程管理中主要数据结构的设计及进程调度算法、进程控制机构、通讯机构的实施。
故而,在实验前,应对进程管理有较为深入理解:
(1)明确信号量机制在进程互斥、同步中的作用;
(2)认清进程调度的基本原则;
(3)熟悉进程状态间的转换原理;
(4)此外,对进程通讯等机制也有了解。
2、概要设计
程序流程图如下页所示:
3、详细设计
3.1主要算法思想:
系统为进程设置3种运行状态:
E--执行态;R--高就绪态;C--完成态。
运行态(Running):
当一个进程在处理机上运行时,则称该进程处于运行状态。
就绪态(Ready):
一个进程获得了除处理机外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。
阻塞态(Blocked):
(又称挂起状态、等待状态):
一个进程正在等待某一事件发生而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。
系统开始时,先初始化三个进程。
然后输出命令菜单,根据用户输入要求,调用功能,创建新进程,就是申请一个新的PCB,然后根据输入信息设置PCB的值即可完成新进程的初始化。
此时判断可用PCB块数为多少,是否可以继续创建新进程,来实现进程的创建的工作。
显示当前的执行进程,先要判断当前的执行进程是什么,即判断当前所有PCB中STATUS为“E”的PCB为那个进程的,然后便可输出相应的进程信息。
换出进程实质上就是更改PCB内数据的值,删除当前执行进程,首先需要找到正在执行的进程,然后删除其PCB,然后寻找当前优先级最高的就绪状态,调为执行状态。
进程间通信实质上时实现进程间BOX结构内信息的交换,当一个进程发送信息后,该进程的BOX设置为可用状态,而接受信息的BOX设置为不可用状态。
显示所有进程信息,即为输出所有有效PCB内的信息。
3.2数据结构:
每个进程有一个进程控制块PCB:
struct{
charname;//
intid;//进程身份(即:
内部标识符,如:
0,1,2)
charstatus;//进程状态,可为E、R和C;
intpriority;//进程优先数;
intflags;//用于标志此PCB是否可用:
//(USE表示PCB已创建orUNUSE表示PCB未创建)
}
pcb[MAX];//PCB[i]的信息
信箱BOX,内容包括:
struct{
charcomer;//信息发送者(sendmessage)
intinfo_num;//发来得信息数(messages'snumber)
intmutex;//信箱同步信号量(USE表示信箱可使用orUNUSE表示信箱不可使用)
intboxflag;//信箱存在否的标志
}
box[MAX];//进程i的信箱
3.3重要的函数模块:
find()这是用来寻找优先级最高的进程的关键函数,即寻找就绪队列中,优先权最高的进程。
在删除,查看当前运行的程序中有很关键的作用,被函数intscheduler()所调用。
寻找到就绪队列中进程优先权最高的进程,就方便了scheduler()函数调用。
intfind()//~~~~~寻找优先权最高的进程~~~~~
{
intj;//用于循环计数
intd,t;
d=0;
for(j=0;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);//返回应调为优先权最高的进程 } 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='r'; pcb[pd].status='e';//将状态变为执行态 exe=pd; } return(exe); } 3.4其他所用函数及其作用 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的内容。 即可完成进程的替换。 3.5宏定义和全局变量 #defineMAX10//最大进程数 #defineNIL-1//用于执行进程为空 #defineUSE0//可用 #defineUNUSE-1//不可用 intexe;//执行进程指针,其值为进程标识数; 五、设计不同实验数据,记录实验结果并分析。 (1)本程序一开始时是进行三个进程的初始化任务,根据提示输入信息即可实现进程PCB的初始化: (2) 输入完三个进程信息后,然后根据命令菜单,输入命令,选择实现向用功能。 如下图: (3)实现1号功能调用: (4)实现2号功能调用,显示当前执行进程信息: (5)实现3号功能调用,换出某个进程信息: (6)实现4号功能调用,杀死运行进程的信息: (7)实现5号功能调用,进程之间的通信的信息,如下图所示: (8)实现6号功能调用,显示所有进程信息: (9)实现7号功能调用,退出系统: 六、实验总结与体会 本实验作为操作系统的课程设计实验,还是具有相当难度的,按照报告的提示和要求,利用指针链表等操作效果更好,但我利用数组方法来实现相应功能。 关于进程间通信的实现,我对相关知识掌握不够熟练,所以此处只是简单的利用BOX结构体实现对于通信的模拟。 本实验的测试结果表明,我所编写的程序基本满足要求。 通过本次实验,加深了我对进程概念及进程管理各部分内容的理解;熟悉了进程管理中主要数据结构的设计及进程调度算法、进程控制机构、同步机构、通讯机构的实施;对进程的调度、执行、阻塞、就绪也有了更进一步的了解;对进程的调度算法及动态改变优先数有了更深的认识。 一个较大的程序通常都由若干个程序段组成,程序在执行时,各程序段必须按照先后次序逐个执行。 进程的三个基本状态: 运行态(Running): 当一个进程在处理机上运行时,则称该进程处于运行状态。 就绪态(Ready): 一个进程获得了除处理机外的一切所需资源,一旦得到处理机即可运行,则称此进程处于就绪状态。 阻塞态(Blocked): (又称挂起状态、等待状态): 一个进程正在等待某一事件发生而暂时停止运行,这时即使把处理机分配给进程也无法运行,故称该进程处于阻塞状态。 关于进程通信,根据自己的理解建立了邮箱,以便于进程与邮箱,进程与进程之间的数据交换。 我使用的就是间接的通信方式,即通过邮箱来实现进程之间的数据交换。 在间接通信情况,消息不直接从发送者发送到接收者,而是发送到暂存消息的共享数据结构组成的队列,这个实体称为信箱(mailbox).因此二个进程通信情况,一个进程发送一个消息到某个信箱,而另一个进程从信箱中摘取消息。 间接通信的使用好处是增加了使用消息的灵活性。 发送者和接收者的关系可能是一对一、多对一,一对多或多对多。 一对一的关系允许一个专用通信链路用于二个进程间的交互,它能使俩进程间交互不受其它进程错误干予的影响,多对一的关系对客户/服务器交互特别有用,一个进程对多个其它进程(用户)提供服务。 在这种情况信箱经常称作为端口(port)。 一对多关系允许一个发送进程和多个接收进程交互,这可用来将消息广播(broadcast)给一组进程。 七、源程序清单及注释程序的源代码为: #include #include #include #defineMAX10//最大进程数 #defineNIL-1//用于执行进程为空 #defineUSE0//可用 #defineUNUSE-1//不可用 intexe;//执行进程指针,其值为进程标识数; struct{ charname; intid;//进程身份(即: 内部标识符,如: 0,1,2) charstatus;//进程状态,可为E、R和C; intpriority;//进程优先数; intflags;//用于标志此PCB是否可用: } pcb[MAX];//PCB[i]的信息 struct{ charcomer;//信息发送者(sendmessage) intinfo_num;//发来得信息数(messages'snumber) intmutex;//信箱同步信号量(USE表示信箱可使用orUNUSE表示信箱不可使用) intboxflag;//信箱存在否的标志 } box[MAX];//进程i的信箱 voidinit();//初始化创建原语 voidcreate();//创建原语 voidanalyse();//判断是否创建新进程 voiddeleted();//终止进程 voiddisplay();//显示当前执行的进程 voiddisplayall();//显示所有进程状态 voidinform();//发送消息函数(进程通信) voidexchage();//换出进程函数 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;j<3;j++) { pcb[j].id=j;//给进程身份(如: 1,2,3...)赋值 pcb[j].status='r';//进程状态 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 { pcb[j].status='c'; pcb[j].flags=UNUSE; box[j].mutex=USE; 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;//给进程身份(如: 1,2,3...)赋值 pcb[rep].status='r';//进程状态(可为E、R、T、W和C) printf("进程%d的名称和优先权为: ",rep);//***输入各进程优先级*** cin>>p>>pri; pcb[rep].name=p; pcb[rep].priority=pri;//*** pcb[rep].flags=USE;//标识PCB已创建 box[rep].boxflag=USE; count[rep]=1;//***修改'可用PCB索引'*** count[MAX]--;//当前还可用的pcb个数 } //创建新的进程 voidanalyse() { charanswer;//用于记录"外存是否还有作业需创建进程"的响应 printf("\n是否要建立新进程? (Y/N)"); TRY: cin>>answer;//取得响应值 if(answer=='y'||answer=='Y') create(); elseif(answer=='n'||answer=='N') return; else { printf("\n输入错误,请重新输入! "); gotoTRY; } intt=0;//用于寻找可用PCB数量 for(intj=0;j { if(pcb[j].flags==UNUSE) t++; }//***************** if(t! =0) { printf("\n是否继续创建进程(Y/N): "); gotoTRY; } } //显示当前执行的进程 voiddisplay() { intn; printf("当前执行的进程为: \n"); n=scheduler(); printf("进程名: %c",pcb[n].name); printf("\n"); } //终止当前执行的进程 voiddeleted() { intn; n=scheduler(); pcb[n].status='c'; pcb[n].flags=UNUSE;//撤消PCB box[n].boxflag=UNUSE; exe=NIL; printf("进程%c已被删除! \n",pcb[n].name); count[MAX]++; } //显示所有进程状态 voiddisplayall() { for(intj=0;j { if(pcb[j].flags==USE) { printf("进程%c状态为: %c\n",pcb[j].name,pcb[j].status); printf("优先权为: %d\n",pcb[j].priority); } } } //进程通信 voidinform() { charrequire; printf("\t是否确定发送信息(Y/N): "); TRY: cin>>require;//取得响应值 if(require=='y'||require=='Y')//*********答案*********** { chargeter,fa; intg,f; intnumber; printf("\t\t请输入发送信息进程名: "); cin>>fa; printf("\t\t请输入接收信息进程名: "); cin>>geter; printf("\t\t输入所要发送信息数: "); cin>>number; for(intmi=0;mi { if(pcb[mi].name==geter) g=pcb[mi].id;//进程身份 } for(intmm=0;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; printf("\t\t通信成功! ! ! \n"); printf("\t已接收到进程%c消息,消息数目是%d.\n",fa,box[g].info_num); box[f].mutex=USE;//清空信箱 } else//否,失败 { printf("\t\t通信失败! 请继续! \n"); return; } } elseif(require=='n'||require=='N')//**********答案************ return; else//**********答案************ { printf("\n输入错误,请重新输入! "); gotoTRY; } } //换出进程函数 voidexchage() { charn,t; inth; printf("请输入要替换的进程名: \n"); cin>>n; printf("请输入新进程名: \n"); cin>>t; cout<<"请输入新增进程的优先权"< cin>>h; for(intm=0;m { if(pcb[m].name==n) { pcb[m].priority=h; pcb[m].name=t; } } printf("进程已成功替换! \n"); } //更改当前的执行进程 intscheduler() { intpd; pd=find(); if(exe==NIL)//***若当前执行程序为无*** { pcb[pd].status='e';//将状态变为执行态 exe=pd; } elseif(pcb[pd].priority>pcb[exe].priority)//判断优先级高低 //若优先级高于当前执行程序 { pcb[exe].status='r'; pcb[pd].status='e';//将状态变为执行态 exe=pd; } return(exe); } //寻找就绪队列中,优先权最高的进程 intfind() { intj;//用于循环计数 intd,t; d=0; for(j=0;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);//返回应调为优先权最高的进程 } //主函数 voidmain() { printf("**************
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 进程 管理