操作系统进程调度实验报告.docx
- 文档编号:10408825
- 上传时间:2023-02-11
- 格式:DOCX
- 页数:31
- 大小:206.91KB
操作系统进程调度实验报告.docx
《操作系统进程调度实验报告.docx》由会员分享,可在线阅读,更多相关《操作系统进程调度实验报告.docx(31页珍藏版)》请在冰豆网上搜索。
操作系统进程调度实验报告
操作系统进程调度实验报告
一.实验目的
用高级语言编写和调试一个进程调度程序~以加深对进程的概念及进程调度算法的解(
进程调度时进程管理的主要内容之一~通过设计~编制~调试一个简单的进程调度模拟系统~对进程调度~进程运行状态变换加深理解和掌握。
模拟计算机操作系统的进程调度,建立进程控制块PCB,要包含有关进程的描述信息,控制信息以及资源信息.模拟系统根据PCB感知进程的存在和通过PCB中所包含的各项变量的变化,掌握进程所处的状态以达到控制进程活动的目的.要实现进程的状态及其转换,进程的创建与撤消,进程的阻塞与唤醒.用P,V原语操作实现进程互斥.
二.实验要求
建立进程控制块PCB,用PCB实现进程在运行过程中的一切状态,未创建、就绪、运行、等待、退出.以完成资源的共享,实现进程的同步与互斥.程序要求用p,v操作实现进程互斥.三.实验平台
WindowsXP下的Microsoftvitualc++平台四.所用语言
MicrosoftVisualC++语言
五.机器要求
MicrosoftWindowsXPProfessional
版本2002
ServicePack
256MB内存
SVGA(800×600分辨率~256色或更高级的显示卡
鼠标或其他相容设备
六.系统分析
设计建立四个进程,模拟模拟批处理多道操作系统的进程调度,
进程调度算法,采用最高优先数优先的调度算法.每个进程有一个进程控制块,PCB,表示。
进程控制块可以包含如下信息:
进程名、优先数、到达时间、需要运行时间、已用CPU时间、进程状态等等。
进程的优先数及需要的运行时间可以事先人为地指定,也可以由随机数产生,。
进程的到达时间为进程输入的时间。
进程的运行时间以时间片为单位进行计算。
每个进程的状态可以是就绪W,Wait,、运行R,Run,、或完成F,Finish,三种状态之一。
就绪进程获得CPU后都只能运行一个时间片。
用已占用CPU时间加1来表示。
如果运行一个时间片后~进程的已占用CPU时间已达到所需要的运行时间~则撤消该进程~如果运行一个时间片后进程的已占用CPU时间还未达所需要的运行时间~也就是进程还需要继续运行~此时应将进程的优先数减1,即降低一级,~然后把它插入就绪队列等待CPU。
每进行一次调度程序都打印一次运行进程、就绪队列、以及
各个进程的PCB~以便进行检查。
重复以上过程~直到所要进程都完成为止。
同时,以上操作执行完了以后,要反映出在这个操作过程中p原语和v原语操作的执行情况,于是调用预先创建的函数.并输出p,v操作在整个程序过程中的执行情况和状态.于是我们创建四个进程process1,process2,process3,process4具体反应p,v原语对四个进程的操作.要预先说明的是,在四个进程并不是与输入的四个进程一一对应.输入的四个进程要按照优先级的高低来确定它们执行的顺序,优先级从高到低顺序执行,所以创建的process1到process4四个进程函数与输入的四个进程的执行顺序是一一对应的,也就是说,优先级最高的与process1对应,依次下来.这样我们创建的四个进程函数才能正确反映p,v原语对四个具体进程的操作过程.
过程运行中除了调用P操作申请信号量外~还要调用V操作释放信号量~V操作在释放信号量之后~还将唤醒因申请此信号量而被阻塞的过程。
在程序运行的四个过程
PROCESS1,PROCESS2,PROCESS3,PROCESS4,~其中过程运行中通过P操作申请信号量1~过程2通过V操作释放信号量2~然后做一次操作申请信号量2。
四个过程的运行通过进程调度模块同意安排~调度模块通过FIND()函数找到第一个就绪过程~如果当前没有过程已在运行~就直接运行此过程~如果有~则比较两者的优先数~然后运行优先权高者。
七.系统功能
因为没有设计动化效果,所以没有对系统功能详细说明.只是输出/输入语句.
八.数据结构
进程控制块1PCB
struct{
intid;
charstatus;
intpriority;
intwaiter1;
}pcb[5];
信号量
struct{
intvalue;
intwaiter2;
}sem[4];
现场保护栈stack
charstack[11][4]
每个进程都有一个大小为10个字的现场保护栈~用来保护被中断时的断点地址等信息。
全局变量
inti;用以模拟一个通用寄存器
charaddr;用以模拟程序计数器
intm1,m2;为系统设置的公用数据被三个进程共享使用
定义进程控制块2PCB
structpcb{
charname[10];
charstate;
intsuper;
intntime;
intrtime;
structpcb*link;
}*ready=NULL,*p;
现场保护栈:
charstack[11][5]
每个进程都有一个大小为11个字的现场保护栈,用来保护被中断时的断点地址等信息.
全局变量
inti;用以模拟一个通用寄存器
charaddr;用以模拟程序计数器
intm1,m2;为系统设置的公用数据被四个进程共享使用.
intnum;确定进程数量
struct{
intid;//进程标号
intwaiter1;//指针~用于标识等待队列的下一个进程
intpriority;//进程优先级
charstatus;//进程状态
}Pcb[5];进程控制快Pcb
九.分工情况
在我们小组合作的过程中,由我们三个人共同完成,具体的分工是这样的:
框图设计和编写程序代码由许向前和申友明共同完成,因为框图和程序紧密相连.
整个幻灯片设计是由杨毅完成
十.讨论情况
第一次讨论
时间:
2005111地点:
12栋116寝室
主持:
申友明
内容:
讨论这次作业的合作和分工情况,并认真阅读老师给的辅助资料.第二次讨论
时间:
20051110地点:
12栋116寝室
主持:
杨毅
内容:
一起参阅了一些相关的资料和源代码,并构建整个作业的大约流程图.第三次讨论
时间:
20051117地点:
12栋116寝室
主持:
许向前
内容:
具体完成了分工操作,并将我们完成的部分集中在一起,反复修改,由
杨毅负责的整个课件基本形成.
最后一次讨论是在
对我们所努力产生的成果从总体上进行包装.作业完成.十一.流程图
流程图一.
流程图二.
流程图三
流程图四
流程图五
流程图六
流程图七
流程图八
流程图九
流程图十
流程图十一.
process4()
add==’m’?
add==’n’
i=1
返回0调用P操作并判断带回值=0?
m1=i
Printf(“proce3callVonsem1m1=%d\n”,m1)
调V操作并判断返回值=0?
Printf(“proce3i=%d\n”,i)
返回0
i=i+10
十二.程序代码
#include
#include
#definegetpch(type)(type*)malloc(sizeof(type))
#defineNULL0
intm1;//共享变量
intm2;//共享变量
struct{
intid;//进程标号
intwaiter1;//指针~用于标识等待队列的下一个进程
intpriority;//进程优先级
charstatus;//进程状态
}Pcb[5];
struct{
intvalue;//信号量的值
intwaiter2;//指针~用于标识等待此信号量队列的第一个
进程
}sem[4];
charstack[11][5];//现场保护堆栈inti;//cpu中的通用寄存器intep;//当前运行进程指针charaddr;//程序运行时的地址voidinit();//初始化
intfind();//找出就绪进程intw2();//
intprocess1();//进程1
intprocess2();//进程2
intprocess3();//进程3
intprocess4();//进程4
intP(int,int,char);//P原语intV(int,int,char);//V原语
//**************************************************
structpcb{/*定义进程控制块PCB*/
charname[10];
charstate;//状态
intsuper;//最先判别优先级
intwaittime;//等待时间
intxtime;
intntime;
intrtime;
structpcb*link;
}*ready=NULL,*p,*t=NULL;
typedefstructpcbPCB;
//*************************************
voidinit()//初始化进程
{
intj,k;
Pcb[0].status='w';//进程状态设置为等待
Pcb[0].priority=5;//进程的优先级别
for(j=1;j<=4;j++)
{
Pcb[j].id=j;//进程编号
Pcb[j].status='r';//进程状态设置为就绪
Pcb[j].waiter1=0;//进程指针初始化为0
Pcb[j].priority=j;//设置进程优先级
}
for(j=1;j<=3;j++)
{
sem[j].value=1;//信号量赋值为1
sem[j].waiter2=0;//等待信号量队列的初始化
}
i=0;//CPU通用寄存器初始化
ep=0;//
addr='0';//程序运行地址
m1=0;//共享变量初始化
m2=0;//共享变量初始化\
for(j=1;j<=10;j++)
{
for(k=1;k<=4;k++)
stack[j][k]='0';//现场保护堆栈初始化
}
}
intfind()
{//查找初始化变量
intj;
for(j=1;j<=4;j++)
if(Pcb[j].status=='r')
return(j);//如果pcb队列中有就绪进程~返回进程编号
return(0);
}
intw2()
{//进程调度程序
intpd;
pd=find();//找出就绪进程编号
if(pd==0)
return(0);//如果没有找到就绪进程~退出程序
elseif(ep==0)
{//如果当前运行进程是否为0
Pcb[pd].status='e';//直接将当前进程设置为运行状态
ep=pd;//当前运行进程设置为pd
printf("进程%d正在执行\n",ep);
}
else
if(Pcb[pd].priority {//调入进程优先级别高 Pcb[ep].status='r';//把CPU运行进程执行状态设置为就绪 printf("读取进程%d\n",Pcb[pd].id); Pcb[pd].status='e';//将待调入进程执行状态设置为执行 ep=pd;//将当前运行进程指针为待调入进程 } printf("运行进程%d\n",ep); i=stack[1][ep];//恢复进程的通用寄存器中的值和运行地址。 addr=stack[2][ep]; switch(ep) {//根据当前运行的进程选择运行 case1: process1(); break; case2: process2(); break; case3: process3(); break; case4: process4(); break; default: printf("当前进程出现错误%d\n",ep); break; } } intprocess1() {//进程1 if(addr=='m') gotom;//如果当前运行地址是m~跳到m运行 i=1; a: printf("进程1在信号量sem[1]上调用P操作\n"); if(P(1,1,'m')==0)return(0);//进行p操作~m表示程序执行到m elsegotom; m: printf("打印进程1...m1=%d\n",m1);//进程1的操作~打印~寄存器i,5 printf("打印进程1...i=%d\n",i); i+=5; gotoa;//跳回a执行 } intprocess2() {//进程分为4部分 if(addr=='m')gotom; if(addr=='n')goton; i=1; a: printf("进程2在信号量sem[2]上调用P操作\n"); if(P(2,2,'m')==0)return(0); m: m1=2*m2; printf("进程2在信号量sem[1]上调用V操作m1=%d\n",m1); if(V(1,2,'n')==0)return(0); else{ n: printf("打印进程2...i=%d\n",i); i+=10; gotoa; } } intprocess3() { if(addr=='m')gotom; if(addr=='n')goton; i=1; a: //if(i>4){ printf("进程3在信号量sem[3]上调用P操作\n"); if(P(3,3,'m')==0)return(0); //} m: m1=3*m2; printf("进程3在sem[2]信号量上调用V操作m=%d\n",m2); if(V(2,3,'n')==0)return(0); else{ n: printf("打印进程3...i=%d\n",i); i+=15; gotoa; } } intprocess4() { if(addr=='m')gotom; if(addr=='n')goton; i=1; a: if(i>4){ printf("进程4在信号量sem[3]上调用P操作\n"); if(P(3,4,'n')==0)return(0); } n: m2=i; printf("进程4在sem[3]信号量上调用V操作m=%d\n",m2); if(V(3,4,'m')==0)return(0); else{ m: printf("打印进程4...i=%d\n",i); i+=1; gotoa; } } intP(intse,intP,charad)//p操作 { intw; sem[se].value--;//信号量减1 if(sem[se].value==0)return (1);//如果信号量,0~返回 1~说明阻塞 printf("阻塞当前进程%d\n",P); Pcb[P].status='w';//改变进程状态 ep=0;//运行进程为空 Pcb[P].waiter1=0;//设为尾末 w=sem[se].waiter2;//找出等待队列的队尾 if(w==0)sem[se].waiter2=P;//插入等待队列 else{ while(Pcb[w].waiter1! =0)w=Pcb[w].waiter1; Pcb[w].waiter1=P; } stack[1][P]=i;//保存现场 stack[2][P]=ad; return(0); } intV(intse,intP,charad)//v操作 { intw; sem[se].value++;//信号量加1 if(sem[se].value>0)return (1);//信号量>0~无等待进程 w=sem[se].waiter2;//返回第一个等待进程 sem[se].waiter2=Pcb[w].waiter1;//调整位置 Pcb[w].status='r';//进程改变状态 printf("唤醒进程%d\n",w); stack[1][P]=i;//进程状态进栈 stack[2][P]=ad; return(0); } sort()/*建立对进程进行优先级排列函数*/ { PCB*first,*second; intinsert=0; if((ready==NULL)||((p->super)>(ready->super))) /*优先级最大者,插入队首*/ { p->link=ready; ready=p; } else/*进程比较优先级,插入适当的位置中*/ { first=ready; second=first->link; while(second! =NULL) { if((p->super)>(second->super))/*若插入进程比当前进程优先数大,*/ {/*插入到当前进程前面*/ p->link=second; first->link=p; second=NULL; insert=1; } else/*插入进程优先数最低,则插入到队尾*/ { first=first->link; second=second->link; } } if(insert==0) first->link=p; } } sort1() { p->link=t; ready=p; } input()/*建立进程控制块函数*/ { inti; //clrscr();/*清屏*/ //printf("\n请输入进程号: "); //scanf("%d",&num); for(i=0;i { printf("\n进程号No.%d: \n",i); p=getpch(PCB); printf("\n输入进程名(字符/字符串): "); scanf("%s",p->name); printf("\n输入进程优先数: "); scanf("%d",&p->super); printf("\n阻塞进程的时间片: "); scanf("%d",&p->waittime); printf("\n进程要运行的时间: "); scanf("%d",&p->ntime); printf("\n阻塞时间: "); scanf("%d",&p->xtime); printf("\n"); p->rtime=0; p->state='w'; p->link=NULL; sort();/*调用sort函数*/ } } intspace() { intl=0; PCB*pr=ready; while(pr! =NULL) { l++; pr=pr->link; } return(l); } disp(PCB*pr)/*建立进程显示函数,用于显示当前进程*/ { printf("\nqname\tstate\twaittime\tndtime\truntime\txtime\n"); printf("%s\t",pr->name);printf(""); printf("%c\t",pr->state);printf(""); printf("%d\t",pr->waittime);printf(""); printf("%d\t",pr->xtime);printf(""); printf("%d\t",pr->ntime);printf(""); printf("%d\t",pr->rtime);printf(""); printf("\n"); } check()/*建立进程查看函数*/ { PCB*pr; PCB*pp; printf("\n**********当前正在运行的进程是: %s",p->name); /*显示当前运行进程*/ disp(p); pr=ready; printf("\n***********当前就绪队列状态为: \n");/*显示就绪队列状态*/ while(pr! =NULL) { disp(pr); pr=pr->link; } pp=t; printf("\n阻塞队列状态为: \n"); while(pp! =NULL) { disp(pp); pp=pp->link; disp(pr); pr=pr->link; } } destroy()/*建立进程撤消函数(进程运行结束,撤消进程)*/ { printf("\n进程[%s]已完成.\n",p->name); free(p); } running()/*建立进程就绪函数(进程运行时间到,置就绪状态*/ { PCB*ptr; while(p->rtime! =p->ntime) { p->rtime++; printf("\n当前所运行的进程状态为: "); disp(p); ptr=t; while(ptr! =NULL) { ptr->xtime--; if(ptr->xtime==0) { p=ptr; sort(); } ptr->link=ptr; } if(p->rtime==p->waittime) { printf("\n该进程被阻塞: "); sort1(); break;} } if(p->rtime==p->ntime) destroy(); } /
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 进程 调度 实验 报告