学生报告课名称操作系统项目名称进程管理模拟.docx
《学生报告课名称操作系统项目名称进程管理模拟.docx》由会员分享,可在线阅读,更多相关《学生报告课名称操作系统项目名称进程管理模拟.docx(16页珍藏版)》请在冰点文库上搜索。
![学生报告课名称操作系统项目名称进程管理模拟.docx](https://file1.bingdoc.com/fileroot1/2023-6/11/15d5957e-061d-4b0b-9f1a-42f4db017496/15d5957e-061d-4b0b-9f1a-42f4db0174961.gif)
学生报告课名称操作系统项目名称进程管理模拟
学生实验报告
实验课名称:
操作系统
实验项目名称:
进程管理模拟系统
专业名称:
计算机科学与技术
班级:
24020504
学号:
2402050416
学生姓名:
张朋长
教师姓名:
刘晓春
2008年06月11日
一、实验项目名称
进程管理模拟系统
二、实验内容
设计一个允许n个进程并发运行的进程管理的模拟系统。
该系统包括简单的进程控制(创建、阻塞、唤醒、调度)、同步及通信机构。
分析系统所需的数据结构、算法的流程以及化分各个功能模块。
并且能够编写相应的程序代码,对其进行测试,分析结果是否正确。
三、实验要求
要求学生熟悉进程概念及进程管理的各部分内容。
要求学生明确进程管理中需要的数据结构、控制机构的基本原理。
将分析程序结果写入“实验结果与分析”中,其中包括:
程序的模块功能、程序的流程。
将对进程管理的实现与概念的联系与体验写入“实验体会与评价”中。
四、实验原理
进程管理包括进程的控制、阻塞、唤醒与撤消。
进程在运行过程中状态在不断的变化。
进程运行过程中,因为竞争资源而需对它们进行同步控制。
所有这些在操作系统中用数据结构PCB来记录,系统通过PCB控制进程的运行。
在单处理机系统中,多道程序的引入,需要进程的调度程序来选择一个进程进行运行。
比如常用的先来先服务、短进程优和优先级优先等等,也可以选择它们的结合调度算法。
例子:
支持多个进程并发运行的简单进程管理模拟系统。
问题描述:
本系统的同步机构采用的信号量上的P、V操作的机制;控制机构包括阻塞和唤醒操作;时间片中断处理程序处理模拟的时间片中断;进程调度程序负责为各进程分配处理机。
系统中设计了3个并发进程.它们之间有如下同步关系:
3个进程需要互斥使用临界资源s2,进程1和进程2又需互斥使用临界资源s1。
本系统在运行过程中随机打印出各进程的状态变换过程,系统的调度过程及公共交量的变化情况。
算法:
系统为进程设置了5种运行状态:
e——执行态;r——高就绪态;t——低就绪态(执行进程因时间片到限而转入):
w——等待态;c——完成态。
各进程的初始状态均设置为r。
系统分时执行各进程。
通过产生随机数x来模拟时间片(每一个时间片并不相同)。
当进程processl访问随机数x时,若x≥0.33;当进程proccss2访问x时,若x<0.33或x≥0.66;当进程process3访问x时,若x<0.66,则分别认为各进程的执行时间片到限,产生“时间片中断”面转入低就绪态t。
进程调度算法采用剥夺式最高优先数法。
各进程的优先数通过键盘输入予以静态设置。
调度程序每次总是选择优先数最小(优先权最高)的就绪进程投入执行。
先从r状态进程中选择,再从t状态进程中选择。
当现行进程唤醒某个等待进程,且被唤醒进程的比先数小于现行进程时,则剥夺现行进程的执行权。
各进程在使用临界资源s1和s2时,通过调用信号量sem1和sem2上的P、V操作来实现同步。
阻塞和唤醒操作负责完成从进程的执行态到等待态以及从就绪态的转变。
系统启动后,在完成必要的系统初始化后便执行进程调度程序。
当执行因“时间片中断”,或者被排斥使用临界资源,或唤醒某个等待进程时,立即进行进程调度。
当3个进程都处于完成状态后,系统退出运行。
数据结构:
每个进程一个PCB,内容:
id 进程标识
status 进程状态
priority 进程优先数
nextwr 等待队链指针,指示在同一信号量上等待的下一个进程的标识。
信号量。
对应于临界资源s1和s2分别有sem1和sem2,均为互斥号量,内容包括:
value 信号量值,初值为1
firstwr 等待链指针,指示在该信号量上第一个等待进程的标识数。
保留区。
用数组saveaera[3][4]表示。
即每个进程都有一个大小为4个单元的保留区,用来保存被“中断”时的现场信息,如通用寄存器的内容和断点地址等。
全程变量。
exe 执行进程指针,其值为进程标识数
i 用来模拟一个通用寄存器。
五、实验流程
实验流程图如下页所示:
六、本次实验源程序
#include
#include
#include
#include
#defineTRUE1
#defineFALSE0
#defineMAXPRI100
#defineNIL-1
struct{
intid;
charstatus;
intnextwr;//*等待链指针,指示在同一信号量上等待的下一个进行进程的标识符*
intpriority;
}pcb[3];
struct
{
intvalue;
intfirstwr;/*等待链首指针,指示该信号量上第一个等待进程的标识数*/
}sem[2];
charsavearea[3][4],addr;
inti,s1=0,s2=0,seed,exe=NIL;
voidinit()
{intj;
for(j=0;j<3;j++)
{
pcb[j].id=j;
pcb[j].status='r';
pcb[j].nextwr=NIL;
cout<<"\nprocess"<";
cin>>i;
pcb[j].priority=i;
}
sem[0].value=1;sem[0].firstwr=NIL;
sem[1].value=1;sem[1].firstwr=NIL;
for(i=0;i<3;i++)
for(j=0;j<4;j++)
savearea[i][j]='0';
}
doublerandom()
{
doublem;
srand(time(0));
m=(1+rand()%3)%3-0.1;
cout<<"randomm="<getchar();
return(m);
}
timeint(charad)/*timesliceinterupt*/
{doublex;
x=random();
if((x<0.33)&&(exe==0))return(FALSE);
if((x<0.66)&&(exe==1))return(FALSE);
if((x<1.0)&&(exe==2))return(FALSE);
savearea[exe][0]=i;
savearea[exe][1]=ad;
pcb[exe].status='t';
cout<<"Thistimessliceinterruptprocess"<exe=NIL;
return(TRUE);
}
find()
{
intj,pd=NIL,w=MAXPRI;
for(j=0;j<3;j++)
{
if(pcb[j].status=='r')
if(pcb[j].priority{
w=pcb[j].priority;
pd=j;
}
}
if(pd==NIL)
for(j=0;j<3;j++)
{
if(pcb[j].status=='t')
if(pcb[j].priority{
w=pcb[j].priority;
pd=j;
}
}
return(pd);
}
scheduler()
{
intpd;
if((pd=find())==NIL&&exe==NIL)
return(NIL);/*quitsystem*/
if(pd!
=NIL)
{
if(exe==NIL)
{
pcb[pd].status='e';
exe=pd;
cout<<"proccess"<}
elseif(pcb[pd].priority{
pcb[exe].status='r';
cout<<"process"<pcb[pd].status='e';
exe=pd;
cout<<"process"<}
}
i=savearea[exe][0];
addr=savearea[exe][1];
return(exe);
}
voidblock(intse)
{
intw;
cout<<"process"<pcb[exe].status='w';
pcb[exe].nextwr=NIL;
if((w=sem[se].firstwr)==NIL)
sem[se].firstwr=exe;
else
{
while(pcb[w].nextwr!
=NIL)
w=pcb[w].nextwr;
pcb[w].nextwr=exe;
}
}
p(intse,charad)
{
if(--sem[se].value>=0)
return(FALSE);
block(se);
savearea[exe][0]=i;
savearea[exe][1]=ad;
exe=NIL;
return(TRUE);
}
voidwakeup(intse)
{
intw;
w=sem[se].firstwr;
if(w!
=NIL)
{
sem[se].firstwr=pcb[w].nextwr;
pcb[w].status='r';
cout<<"process"<}
}
v(intse,intad)
{
if(++sem[se].value>0)
return(FALSE);
wakeup(se);
savearea[exe][1]=ad;
savearea[exe][0]=i;
return(TRUE);
}
voideexit(intn)
{
pcb[n].status='c';
cout<<"process"<\n";
exe=NIL;
}
voidprocess1()
{
if(addr=='a')gotoa1;
if(addr=='b')gotob1;
if(addr=='c')gotoc1;
if(addr=='d')gotod1;
if(addr=='e')gotoe1;
if(addr=='f')gotof1;
for(i=0;i<3;i++)/*如果程序执行超过5次,则*/
{
cout<<"process1callsPonthesemaphore1\n";
if(p(0,'a'))break;/*process1isblocked*/
a1:
cout<<"process1isexecutinginthecreticalsection1\n";
if(timeint('b'))break;/*timesilceinterrupt*/
b1:
cout<<"s1="<<++s1<cout<<"process1callsVonsemaphorelandquitcreticalsection1.\n";
if(v(0,'c'))break;/*wakeupablockedprocess*/
c1:
cout<<"process1callsPonsemaphorel2.\n";
if(p(1,'d'))break;
d1:
cout<<"process1isexectingcreticalsection2.\n";
if(timeint('e'))break;
e1:
cout<<"s2="<<++s2<cout<<"process1callsVonsemaphore2andquitcreticalsection2.\n";
if(v(1,'f'))break;/*wakeupablockprocess*/
f1:
cout<<"process1cyclecount="<
}
if(i<3)return;
eexit(0);
}
voidprocess2()
{
if(addr=='a')gotoa2;
if(addr=='b')gotob2;
if(addr=='c')gotoc2;
if(addr=='d')gotod2;
if(addr=='e')gotoe2;
if(addr=='f')gotof2;
for(i=1;i<6;++i)
{
cout<<"process2callPonsemaphore2\n";
if(p(1,'a'))break;/*process2isblocked*/
a2:
cout<<"process2isexecutingonthecreticalsetion2\n";
if(timeint('b'))break;
b2:
cout<<"s2="<<++s2<cout<<"process2iscallsVonsemaphore2andquitcreticalsection2.\n";
if(v(1,'c'))break;/*wakeupablockedprocess*/
c2:
cout<<"process2callPonsemphore1.\n";
if(p(0,'d'))break;/*process2isblocked*/
d2:
cout<<"process2isexecutingcreticalsetion1\n";
if(timeint('e'))break;
e2:
cout<<"s1="<<++s1<cout<<"process2callVonsemaphorelandquitcreticalsetion2\n";
if(v(0,'f'))break;/*wkupupablockprocess*/
f2:
cout<<"process2cyclecount="<
}
if(i<6)return;
eexit
(1);
}
voidprocess3()
{
if(addr=='a')gotoa3;
if(addr=='b')gotob3;
if(addr=='c')gotoc3;
for(i=1;i<6;++i)
{
cout<<"process3callPonsemaphore2\n";
if(p(1,'a'))break;/*process3isblocked*/
a3:
cout<<"process3isexecutingonitscreticalsection.\n";
if(timeint('b'))break;
b3:
cout<<"s2="<<++s2;
cout<<"process3callsVonsemaphoreandquitcreticalsection.\n";
if(v(1,'c'))break;/*wakeupablockedprocess*/
c3:
cout<<"process3cyclencount="<
}
if(i<6)return;
eexit
(2);
}
voidmain()
{
intj=0;
intk;
charm;
cout<<"****processmanagement****\n\n";
init();
cout<<"s1="<cout<<"process1,process2,process3areallinready!
\n";
for(;;)
{
j=j+1;
cout<<"\n"<getchar();
if((k=scheduler())!
=NIL)
{
switch(k)
{
case0:
process1();
break;
case1:
process2();
break;
case2:
process3();
break;
default:
cout<<"processidentifererror\n";
break;
}
}
elsebreak;
}
cout<<"s1="<cout<<"\n****END****\n";
}
七、实验体会与评价
操作系统一定要引入进程的概念哪,主要从两个方面来看:
从理论角度看,是对正在运行的程序过程的抽象;从实现角度看,是一种数据结构,目的在于清晰地刻划动态系统的内在规律,有效管理和调度进入计算机系统主存储器运行的程序。
本次试验主要是熟悉进程概念及进程管理的各部分内容,并明确进程管理中需要的数据结构、控制机构的基本原理。
进程的同步机制包括互斥和同步。
互斥是指一组并发进程中的两个或多个程序段,因共享某一公有资源而导致它们必须以一个不允许交叉执行的单位执行;同步指的是在异步环境下的一组并发进程,因直接制约而互相发送信号而进行互相合作、互相等待,使得各进程按一定的速度执行的过程。
而本实验是通过P、V原语来实现这种机制。
进程状态分为就绪、等待、执行三个状态。
进程从等待状态到运行状态,必须经过就绪状态,不能直接转换到运行状态;进程由运行状态变为等待状态一般是由运行进程自己主动提出的;进程由等待状态转变为就绪状态总是由外界事件引起的,而不是由该进程自己引起的。
本次实验的进程管理机制过程是:
先判断是否有时间片中断,否的话则跳过此状态的改变,进行下面的判断;有的话就将该进程的状态改为t,再从t状态进程中选择。
当现行进程唤醒某个等待进程,且被唤醒进程的优先数小于现行进程时,则剥夺现行进程的执行权。
然后通过PV操作实现对临界资源的使用,最后等三个进程都处于完成状态时,结束运行。
通过为每个进程分配一个PCB,PCB中记录了操作系统所需的,用于描述进程当前状态以及进程控制运行的全部信息,然后通过产生随机数x来模拟时间片。
接着利用从键盘输入的优先级顺序,每次选择优先数最小(优先权最高)的就绪进程投入执行。