操作系统实验三分析解析.docx

上传人:b****2 文档编号:156031 上传时间:2023-04-28 格式:DOCX 页数:15 大小:18.36KB
下载 相关 举报
操作系统实验三分析解析.docx_第1页
第1页 / 共15页
操作系统实验三分析解析.docx_第2页
第2页 / 共15页
操作系统实验三分析解析.docx_第3页
第3页 / 共15页
操作系统实验三分析解析.docx_第4页
第4页 / 共15页
操作系统实验三分析解析.docx_第5页
第5页 / 共15页
操作系统实验三分析解析.docx_第6页
第6页 / 共15页
操作系统实验三分析解析.docx_第7页
第7页 / 共15页
操作系统实验三分析解析.docx_第8页
第8页 / 共15页
操作系统实验三分析解析.docx_第9页
第9页 / 共15页
操作系统实验三分析解析.docx_第10页
第10页 / 共15页
操作系统实验三分析解析.docx_第11页
第11页 / 共15页
操作系统实验三分析解析.docx_第12页
第12页 / 共15页
操作系统实验三分析解析.docx_第13页
第13页 / 共15页
操作系统实验三分析解析.docx_第14页
第14页 / 共15页
操作系统实验三分析解析.docx_第15页
第15页 / 共15页
亲,该文档总共15页,全部预览完了,如果喜欢就下载吧!
下载资源
资源描述

操作系统实验三分析解析.docx

《操作系统实验三分析解析.docx》由会员分享,可在线阅读,更多相关《操作系统实验三分析解析.docx(15页珍藏版)》请在冰点文库上搜索。

操作系统实验三分析解析.docx

操作系统实验三分析解析

 

实验三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操函数,并画出这两个函数的流程。

答:

函数分析如上述代码,并加以注释

 

down函数流程图

开始

 

Sname,pid

 

N

是否存在输

入的信号量

Y

 

是否存在输

入的进程号

 

N

Y

Count--

 

Count>=0

Y

Y

等待队列

N

是否为空

 

信号量不存在添加到队列的最后置于等待队列队首进程不存在

 

up函数流程图

开始

 

Sname

 

N

是否存在输

入的信号量

 

Y

Count++

 

是否有进程处

于等待队列

 

Y

 

等待队列依次获得资源显示所输入信号浪不存在

 

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()函数,分别为申请资源与释放资源。

在运行的过程中,也出现了一些问题,比如说,如下图所示的问题,会出现进程卡死的问题,

现在我还不是很清楚问题的原因究竟是什么。

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 人文社科

copyright@ 2008-2023 冰点文库 网站版权所有

经营许可证编号:鄂ICP备19020893号-2