PV原语的模拟实现
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
P V原语的模拟实现 This manuscript was revised by the office on December 22, 2012
P、V原语的模拟实现
一、实验目的
本课题实习的目的是,加深对进程概念及进程管理各部分内容的理解;熟悉进程管理中主要数据结构的设计及进程调度算法,进程控制机构、同步结构、通迅机构的实施。
要求设计一个允许n个进程并发运行的进程管理模拟糸统。
该糸统包括有简单的进程控制、同步及通迅机构,其进程调度算法可任意选择。
每个进程用一个PCB表示,其内容可根据具体情况设置。
各进程之间应有一定的同步关糸。
糸统在运行过程中应能显示或打印各进程的状态及有关参数的变化情况,以便观察诸进程的运行过程及糸统的管理过程。
1)理解信号量相关理论;
2)掌握记录型信号量结构;
3)掌握P、V原语实现机制。
二、实验要求
1)输入给定代码;
2)进行功能测试并得出正确结果。
3)分析P和V函数功能模块;
4)在实验报告中画出P和V函数流程图;
5)撰写实验报告。
三、实验内容
本实验针对操作系统中信号量相关理论进行实验,要求实验者输入实验指导书提供的代码并进行测试。
代码主要模拟信号量的P操作和V操作。
1)信号量
信号量也称为信号锁,主要应用于进程间的同步和互斥,在用于互斥时,通常作为资源锁。
信号量通常通过两个原子操作P和V来访问。
P操作使信号量的值+1,V操作使信号量的值-1。
2)记录型信号量
记录型信号量采用了“让权等待”的策略,存在多个进程等待访问同一临界资源的情况,所以记录型信号量需要一个等待链表来存放等待该信号量的进程控制块或进程号。
在本实验中,使用记录型信号量。
四、功能测试
五.
#include<stdio.h>
#defineTRUE1
#defineFALSE0
#defineMAXPRI100
#defineNIL-1
struct{
intid;
charstatus;
intnextwr;
intpriority;
}pcb[1];
struct{
intvalue;
intfirstwr;
}sem[2];
charsavearea[1][3],addr;
inti,s1,s2,seed,exe=NIL;
init()
{intj;
for(j=0;j<1;j++)
{
pcb[j].id=j;
pcb[j].status='r';
pcb[j].nextwr=NIL;
printf("\nprocess%dpriority",j+1);
scanf("%d",&i);
pcb[j].priority=i;
}
sem[0].value=1;sem[0].firstwr=NIL;
sem[1].value=1;sem[1].firstwr=NIL;
for(i=1;i<1;i++)
for(j=0;j<3;j++)
savearea[i][j]='0'; }
floatrandom()
{intm;
if(seed<0)
m=-seed;
elsem=seed;
seed=(24151*seed+11839)%64416;
return(m/12565.0);
}
timeint(charaddr)
{
floatx;
x=random();
if((x<0.11)&&(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]=addr;
pcb[exe].status='t';
printf("Timessilceinterrupt'\nprocess%denterintoready.\n",exe+1); exe=NIL;
return(TRUE);
}
find()
{
intj,pd=NIL,w=MAXPRI;
for(j=0;j<1;j++)
if(pcb[j].status=='r')
if(pcb[j].priority<w){
w=pcb[j].priority;pd=j;
}
if(pd==NIL)
for(j=0;j<1;j++)
if(pcb[j].status=='t')
if(pcb[j].priority<w)
{
w=pcb[j].priority;pd=j;
}
return(pd);
}
scheduler()
{
intpd;
if((pd=find())==NIL&&exe==NIL)
return(NIL);
if(pd!=NIL){
if(exe==NIL)
{
pcb[pd].status='e';
exe=pd;
printf("process%disexecuting.\n",exe+1);
}
elseif(pcb[pd].priority<pcb[exe].priority){
pcb[exe].status='r';
printf("process%denterintoready\n",exe+1);
pcb[pd].status='e';
exe=pd;
printf("process%denterintoready\n",exe+1);
}
}
i=savearea[exe][0];
addr=savearea[exe][1];
return(exe);
}
block(intse)
{
intw;
printf("process%disblocked\n",exe+1);
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);
}
wakeup(intse)
{
intw;
w=sem[se].firstwr;
if(w!=NIL){
sem[se].firstwr=pcb[w].nextwr;
pcb[w].status='r';
printf("process%diswakenup\n",w+1);
}
}
v(intse,charad)
{
if(++sem[se].value>0)return(FALSE);
wakeup(se);
savearea[exe][1]=ad;
savearea[exe][0]=i;
return(TRUE);
}
eexit(intn)
{
pcb[n].status='c';
printf("process%discompleted!\n",n+1);
exe=NIL;
}
processl()
{
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=1;i<6;i++)
{
printf("process1callsPonthesemaphore1\n");
if(p(0,'a'))break;
a1:printf("process1isexecutinginthecreticalsection1\n");
if(timeint('b'))break;
b1:printf("s1=%d\n",++s1);
printf("process1callsVonsemaphorelandquitcreticalsection1\n"); if(v(0,'c'))break;
c1:printf("process1callsPonesemaphorel2\n");
if(p(1,'d'))break;
d1:printf("process1isexectingcreticalsection2\n");
if(timeint('e'))break;
e1:printf("s2=%d\n",++s2);
printf("process1callsVonsemaphore2andquitcreticalsection2\n"); if(v(1,'f'))break;
f1:printf("process1cyclecount=%d\n",i);
}
if(i<6)return;
eexit(0);
}
process2()
{
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){
printf("process2callsPonthesemaphore2\n");
if(p(1,'a'))break;
a2:printf("process2isexecutinginthecreticalsection2\n");
if(timeint('b'))break;
b2:printf("s2=%d\n",++s2);
printf("process2callsVonsemaphore2andquitcreticalsection2.\n"); if(v(1,'c'))break;
c2:printf("process2callsPonesemaphore1.\n");
if(p(0,'d'))break;
d2:printf("process2isexectingcreticalsection1.\n");
if(timeint('e'))break;
e2:printf("s1=%d\n",++s1);
printf("process2callsVonsemaphore1andquitcreticalsection1.\n"); if(v(0,'f'))break;
f2:printf("process2cyclecount=%d\n",i);
}
if(i<6)return;
eexit(1);
}
process1()
{
if(addr=='a')gotoa1;
if(addr=='b')gotob1;
if(addr=='c')gotoc1;
for(i=1;i<6;++i){
printf("process1,callsPonsemaphore2\n");
if(p(1,'a'))break;///*process1isbiocked*/
a1:printf("process1isexeccutingonitscreticalsection\n");
if(timeint('b'))break;
b1:printf("s2=%d\n",++s2);
printf("process1callsVonsemapore2andquitcreticalsection\n");
if(v(1,'c'))break;//*wakeupabiockedprocess*/
c1:printf("process1cyciencount=%d\n",i);
}
if(i<6)return;
eexit(2);
}
main()
{
intk;
printf("****processmanagement****\n\n");
init();
printf("s1=%d,s2=%d\n",s1,s2);
printf("process1,process2,process1areallinready!\n");
for(;;)
if((k=scheduler())!=NIL)
switch(k)
{
case0:process1();
break;
case1:process2();
break;
case2:process1();
break;
default:printf("processidentifererror\n");
break;
}
elsebreak;
printf("s1=%d,s2=%d\n",s1,s2);
printf("\n****END****\n");
}。