操作系统实验三分析解析.docx
- 文档编号:12596641
- 上传时间:2023-04-20
- 格式:DOCX
- 页数:17
- 大小:326.56KB
操作系统实验三分析解析.docx
《操作系统实验三分析解析.docx》由会员分享,可在线阅读,更多相关《操作系统实验三分析解析.docx(17页珍藏版)》请在冰豆网上搜索。
操作系统实验三分析解析
实验三P、V原语的模拟实现
一、实验目的
1)理解信号量相关理论;
2)掌握记录型信号量结构;
3)掌握P、V原语实现机制。
二、实验内容
本实验针对操作系统中信号量相关理论进行实验,要求实验者输入实验指导书提供的代码并进行测试。
代码主要模拟信号量的P操作(down)和V操作(up)。
1)信号量
信号量也称为信号锁,主要应用于进程间的同步和互斥,在用于互斥时,通常作为资源锁。
信号量通常通过两个原子操作dwon(P)和up(V)来访问。
dwon操作使信号量的值+1,up操作使信号量的值-1。
2)记录型信号量
记录型信号量采用了“让权等待”的策略,存在多个进程等待访问同一临界资源的情况,所以记录型信号量需要一个等待链表来存放等待该信号量的进程控制块或进程号。
在本实验中,使用记录型信号量。
三、实验要求
1)输入给定代码;
2)进行功能测试并得出正确结果。
3)分析dwon和up函数功能模块;
4)在实验报告中画出dwon和up函数流程图;
5)撰写实验报告。
四、程序清单
#include"basic.h"
semphoresem[5];//deinfe5semphores
pnode*pr[20];//define0-19total20process
//downoperation
voiddown(char*sname,intpid)
{
intfflag,pflag;
pnode*p,*p1;
semphore*s;
fflag=0;
pflag=0;
for(inti=0;i<5;i++)
if(!
strcmp(sem[i].name,sname))//findsemaphorebyname根据名字找到信号量
{
s=&sem[i];//将找到的信号量存入s
fflag=1;//设置信号量标志位fflag为1,表示找到了信号量
break;
}
for(i=0;i<20;i++)//findpcbbypid根据pid找到pcb进程
if(pr[i]->node->pid==pid)
{
p1=pr[i];//存入p1
pflag=1;//设置进程标志位pflag为1,表示找到了pcb
break;
}
if(!
fflag)//semaphoreisnotexist如果找不到资源信号量
{
printf("thesemphore'%s'isnotexist!
\n",sname);//输出没有该信号量
return;
}
if(!
pflag)//pidisnotexist如果找不到pcb进程
{
printf("theprocess'%d'isnotexist!
\n",pid);//输出没有该pcb进程
return;
}
s->count--;//semaphore!
svalue-1被该pcb进程占用的资源信号量减1
if(s->count>=0)//thispcbgetthesemaphore如果当前资源信号量没有被用完
s->curpid=p1->node->pid;//当前pcb进程就占用该信号量
else
{
if(s->wlist)//thelinkisnotNULL,addthepcbtothelast如果等待链表不为空,就去//找等待链表的尾部插入;若当前pcb进程所占用的信号量没有了,就将该进程放到该进程//链表的尾部去等待
{
for(p=s->wlist;p->next;p=p->next);
p->next=p1;
}
else//thispcbisthefirstpcbbeaddedtothedownlist若等待链表为空,则该pcb进
//程是一个等待的pcb进程,直接插入
s->wlist=p1;
}
}
//upoperation
voidup(char*sname)//释放资源信号量
{
intfflag=0;
for(inti=0;i<5;i++)
if(!
strcmp(sem[i].name,sname))//findthesemaphorebyname由名字找到要释放的资源信号量
{
fflag=1;//将资源信号量标志设为1
break;
}
if(fflag)//findit如果找到
{
sem[i].count++;//该资源信号量加1表示释放
if(sem[i].wlist)//thereareprocessesinthedownlist若等待链表中有请求该资源信号//量的pcb进程
{
sem[i].curpid=sem[i].wlist->node->pid;//信号量被在等待链表中的第一个pcb
//进程占用
sem[i].wlist=sem[i].wlist->next;//等待链表指向下一个等待的pcb进程
}
}
else
printf("thesemphore'%s'isnotexist!
\n",sname);//若找不到该信号量就输出
}
//showsemphoreinfomation
voidshowdetail()
{
inti;
pnode*p;
printf("\n");
for(i=0;i<5;i++)
{
if(sem[i].count<=0)
{
printf("%s(current_process%d):
",sem[i].name,sem[i].curpid);
p=sem[i].wlist;
while(p)
{
printf("%5d",p->node->pid);
p=p->next;
}
}
else
printf("%s:
",sem[i].name);
printf("\n");
}
}
/***************************************************************/
voidinit()
{
//initsemaphore
strcat(sem[0].name,"s0");
strcat(sem[1].name,"s1");
strcat(sem[2].name,"s2");
strcat(sem[3].name,"s3");
strcat(sem[4].name,"s4");
for(inti=0;i<5;i++)
{
sem[i].wlist=NULL;
sem[i].count=1;
}
//initprocess
for(i=0;i<20;i++)
{
pr[i]=newpnode;
pr[i]->node=newpcb;
pr[i]->node->pid=i;
pr[i]->brother=NULL;
pr[i]->next=NULL;
pr[i]->sub=NULL;
}
}
voidmain()
{
shortcflag,pflag;
charcmdstr[32];
char*s,*s1,*s2;
initerror();
init();
for(;;)
{
cflag=0;
pflag=0;
printf("cmd:
");
scanf("%s",cmdstr);
if(!
strcmp(cmdstr,"exit"))//exittheprogram
break;
if(!
strcmp(cmdstr,"showdetail"))
{
cflag=1;
pflag=1;
showdetail();
}
else
{
s=strstr(cmdstr,"down");//createprocess
if(s)
{
cflag=1;
//getparameter
s1=substr(s,instr(s,'(')+1,instr(s,',')-1);
s2=substr(s,instr(s,',')+1,instr(s,')')-1);
if(s1&&s2)
{
down(s1,atoi(s2));
pflag=1;
}
}
else
{
s=strstr(cmdstr,"up");//deleteprocess
if(s)
{
cflag=1;
s1=substr(s,instr(s,'(')+1,instr(s,')')-1);
if(s1)
{
up(s1);
pflag=1;
}
}
}
}
if(!
cflag)
geterror(0);
elseif(!
pflag)
geterror
(1);
}
}
/*******************************************************************/
五、测试要求
1)至少进行10次以上的wait和signal操作;
2)要求wait操作出现进程等待队列;
3)对有等待队列的信号量进行signal操作。
六、实验指导
实验中提供了5个信号量(s0-s4)和20个进程(pid0-19)。
在程序运行过程中可以键入downup命令和showdetail命令显示每个信号量的状态。
具体输入解释如下:
1)dwon获取信号量操作(P操作)。
参数:
1sname2pid。
示例:
down(s1,2)。
进程号为2的进程申请名字为s1的信号量。
2)up释放信号量操作(V操作)。
参数1sname。
示例:
up(s1)。
释放信号量名字为s1的信号量。
3)showdetail显示各信号量状态及其等待队列。
4)exit退出命令行。
七、实验过程
这是为每个进程申请的信号量的状态
0号信号量拥有进程0,1,2,3;1号信号量拥有进程4,5,6,7;2号信号量拥有进程8,9,10,11;
3号信号量拥有进程12,13,14,15;4号信号量拥有进程16,17,18,19.
这是删除s0信号量中的0号进程,此时进程1占用该信号量
这是删除s1信号量中的4号进程,此时进程5占用该信号量
这是删除s2信号量中的8号进程,此时9号进程占用该信号量
这是删除s3信号量的两个进程
这是为0进程申请了s0号信号量,然后又释放了s0信号量中的3号进程
这是先释放0号,4号进程,然后为0号进程申请s0号信号量
这是先释放进程号为0和1的进程,然后再为1号进程申请s1信号量
这是为进程号为1,2,3,4的进程先申请s0信号量,然后再释放进程,直至全部释放完毕
这是先为进程号为1,2,3,4的进程申请信号量,然后释放1进程,再为1号进程申请信号量
先释放资源成功了,然后为0号进程申请信号量,再释放0号进程
八、实验思考
1)读懂down和up操函数,并画出这两个函数的流程。
答:
函数分析如上述代码,并加以注释
2)如何修改down操作,使之能一次申请多个信号量?
答:
假设可一次获取三个信号量
down(s1,s2,s3,1)
s1=substr(s,instr(s,‘(’)+1,instr(s,’,’)-1);
s1s=substr(s,instr(s,’,’)+1,instr(s,’)’));
s2=substr(s1s,0,instr(s1s,’,’)-1);
s2s=substr(s1s,instr(s1s,’,’)+1,instr(s1s,’)’));
s3=substr(s2s,0,instr(s2s,’,’)-1);
s3s=substr(s2s,instr(s2s,’,’)+1,instr(s2s,’)’));
s4=substr(s3s,0,instr(s3s,’)’)-1);
if(s1&&s2&&s3&&s4)
{
down(s1,atoi(s4));
down(s2,atoi(s4));
down(s3,atoi(s4));
pflag=1;
}
3)在某个时刻,一个进程最多可以等待多少个信号量?
答:
一个进程最多可以等待的信号量数目不限。
九、实验总结
这次实验主要是为进程申请资源信号量,然后在等待链表中排队,等待进程调用。
down()函数和up()函数分别对应于教材上的wait()函数与signal()函数,分别为申请资源与释放资源。
在运行的过程中,也出现了一些问题,比如说,如下图所示的问题,会出现进程卡死的问题,现在我还不是很清楚问题的原因究竟是什么。
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 操作系统 实验 分析 解析