操作系统PV原语.docx

上传人:b****5 文档编号:2799696 上传时间:2022-11-15 格式:DOCX 页数:32 大小:36.86KB
下载 相关 举报
操作系统PV原语.docx_第1页
第1页 / 共32页
操作系统PV原语.docx_第2页
第2页 / 共32页
操作系统PV原语.docx_第3页
第3页 / 共32页
操作系统PV原语.docx_第4页
第4页 / 共32页
操作系统PV原语.docx_第5页
第5页 / 共32页
点击查看更多>>
下载资源
资源描述

操作系统PV原语.docx

《操作系统PV原语.docx》由会员分享,可在线阅读,更多相关《操作系统PV原语.docx(32页珍藏版)》请在冰豆网上搜索。

操作系统PV原语.docx

操作系统PV原语

P(sem)的意思是sem-=1;如果此时sem>=0,说明本次资源请求可以满足,p操作可以返回,执行该进程下面的语句;如果此时sem<0,说明本次资源请求不能满足,进入等待队列,然后转进程调度执行其他进程。

V(sem)的意思是sem+=1;如果此时sem>0,说明没有其他进程在等待该资源,v操作可以返回;如果sem<=0,说明未加1前sem<0,即有其他进程在等待这个刚刚释放的资源,于激活等待队列里一个等待该资源的进程,然后v操作也返回。

Sem>=0时表示剩余资源的数量,Sem<0时表示等待该资源的进程的个数。

注意信号量只能放在P或V操作中,用于加减或其他操作都是错误的,另外对同一信号量,P、V操作次数要相等。

1.p1—p6是并发进程,关系如图

完整C语言代码

信号量fi表示Pi已完成,初始值都是0(表示均未完成)

Semaphoref1=0,f2=0,f3=0,f4=0,f5=0,f6=0;

main()

{

cobegin

p1();

p2();

p3();

p4();

p5();

p6();

coend

}

P1()

{

其他语句;

V(f1);

}

P2()

{

P(f1);

其他语句;

V(f1);

V(f2);

}

P3()

{

P(f1);

其他语句;

V(f1);

V(f3);

}

P4()

{

P(f2);

其他语句;

V(f2);

V(f4);

}

P5()

{

P(f2);

其他语句;

V(f2);

V(f5);

}

P6()

{

P(f3);

P(f4);

P(f5);

其他语句;

V(f3);

V(f4);

V(f5);

V(f6);

}

本题写的是完整代码,多数情况下只需要写过程,过程多数属于循环动作,采用死循环。

P、V操作主要用于互斥和同步。

互斥属于间接制约,受资源数量限制;同步属于直接制约,用于控制各过程的前后次序。

2.生产者-消费者问题

一个生产者和一个消费者之间只有同步关系,多个生产者之间还需要用到互斥,多个消费者之间也需要用到互斥

代码如下

存在空单元才可以生产(有地方存),存在满单元才可以消费(有库存取)。

信号量avail代表缓冲区中空单元数量,初值可设为n;full表示满单元数量,初值可设为0;mutex用于互斥,初值为1。

生产者过程

Deposit():

Begin

P(avail)

P(mutex)

送数据入缓冲区某单元

V(mutex)

V(full)

end

消费者过程

remove():

Begin

P(full)

P(mutex)

取缓冲区某单元数据

V(mutex)

V(avail)

end

这两个过程在这里只执行了一次,也可以视题意放在死循环里(多数情况是循环生产和消费)。

另外要注意P操作要考虑次序,用于互斥的P操作多数情况下放后面(不绝对,要自己分析)。

本题中若颠倒次序,会发生死锁(消费者先抢到mutex资源,却没有满单元,生产者虽然有空单元,但却卡在前面对mutex的请求上)

3.读写者问题

多个进程可以同时读某数据(此时不可写),只允许一个进程写数据(此时不可读)。

代码如下:

rc是全局变量,代表读者人数,初值为0;db是信号量,代表允许写,初值为1(只允许1个人写);mutex是信号量,对全局变量要互斥操作,因此使用mutex,初值为1;读者人数达到1就不可写,读者人数为0时可写。

reader():

begin

L1:

P(mutex)

rc=rc+1

if(rc==1)thenp(db)

v(mutex)

读操作

P(mutex)

rc=rc-1

if(rc==0)thenv(db)

v(mutex)

GotoL1

end

writer():

begin

L2:

P(db)

写操作

V(db)

GotoL2

end

以上代码中,如果一直有人在读,那么写永远没有机会,因此可以增加一个信号量w,初始值为1,代表允许新读者进入,这样当有人想执行写时,就不再允许新读者进入,旧读者总有读完离开的时候,这样写就有机会得到执行。

代码如下

reader():

begin

L1:

P(w)

P(mutex)

rc=rc+1

if(rc==1)thenp(db)

v(mutex)

v(w)

读操作

P(mutex)

rc=rc-1

if(rc==0)thenv(db)

v(mutex)

GotoL1

end

writer():

begin

L2:

P(w)

P(db)

写操作

V(db)

V(w)

GotoL2

end

4.哲学家用餐问题

五个哲学家围成一圈,五根筷子放在每人两侧,拿到两根筷子的可以用餐,没拿到足够筷子的只能等别人吃完放下筷子才能得到足够的筷子。

如果不考虑死锁,每个哲学家的用餐过程如下(i表示哲学家的号码(0-4),左手边筷子号为i,右手边筷子号为(i+1)%5,每个筷子都是资源,用信号量表示),i表示哲学家序号,则每人代码如下

pp(i)

begin

p(stick[i])//拿左边筷子

p(stick[(i+1)%5])//拿右边筷子

用餐

V(stick[i])

V(stick[(i+1)%5])

End

根据实际情况,吃饭过程可以不用死循环。

如果程序写成这样,则存在每个人都拿到左边筷子的死锁情况,预防死锁只要破坏以下4条中的1条:

1.互斥2.允许部分分配3.不剥夺4.循环等待

给资源分先后等级(必须先取得等级高的资源,才能去申请下一等级资源),就可以破坏循环等待条件,从而避免死锁。

本题可以让偶数号码的哲学家先申请左手筷子,再申请右手筷子;让奇数号码的哲学家先申请右手筷子,再申请左手筷子。

这样五跟筷子中的0,2,4成了五个人第一步抢夺的筷子,抢到者才能继续申请1,3,把筷子分成两个等级,从而避免了死锁

代码如下

pp(i)

begin

if(imod2==0)thenbegin

p(stick[i])//拿左边筷子

p(stick[(i+1)%5])//拿右边筷子

end

else

begin

p(stick[(i+1)%5])//拿右边筷子

p(stick[i])//拿左边筷子

end

用餐

V(stick[i])

V(stick[(i+1)%5])

End

5.理发师问题

理发馆有1把理发用的椅子,5把等待座椅,顾客进来后如果没人就坐到理发椅上,有人正在理发就坐到等待椅上,如果等待椅也满了就直接离开。

理发师看到理发椅上坐了人就理发,顾客理发完毕就离开。

描述理发师和顾客的行为。

分析顾客和理发师的行为

顾客:

理发师:

(属于循环动作)

顾客数>=6则离开

否则顾客数+1

申请等待椅

申请理发椅

释放等待椅

发现有人坐到理发椅并准备好,就开始理发,告知理发完毕

释放理发椅

离开(顾客数-1)

定义全局变量waiting,用于统计顾客人数,初值为0;定义信号量mutex,对waiting进行操作时起互斥作用,初值为1;定义信号量bchair表示理发椅个数,初值为1;定义信号量wchair表示等待椅个数,初值为5;定义信号量ready表示顾客坐到理发椅后准备好理发,初值为0;定义信号量finish表示理发完毕,初值为0。

Barber():

Begin

L1:

P(ready)

理发

V(finish)

GotoL1

End

Customers():

Begin

L1:

//这里用死循环表示不断有顾客来

P(mutex)

If(waiting<6)thenbegin

Waiting+=1

V(mutex)

Elsebegin

V(mutex)

Return//(离开)

End

P(wchair)//申请等待椅

P(bchair)//申请理发椅

V(wchair)//申请到理发椅后释放等待椅

V(ready)//向理发师发出准备好信号

P(finish)//收到理发师理发完毕信号

V(bchair)//释放理发椅

P(mutex)

Waiting-=1

V(mutex)

Return//(离开)

GotoL1

End

7.P1、P2、P3互斥使用一个N单元的缓冲区,P1用produce()生成一个正整数,用put(x)把该数放入缓冲区某一空单元;P2用getodd()从缓冲区取出一个奇数,用countodd()统计奇数个数;P3用geteven()从缓冲区取出一个偶数,用counteven()统计偶数个数,写出P1、P2、P3。

P1、P2、P3显然和生产者-消费者问题类似,有一个生产者,两个消费者,消费产品的类型不同,因此生产时也要区分产品类型,并且这3个进程可以写成死循环。

定义信号量empty,表示空单元个数,初值为N;定义信号量odd表示放奇数单元的个数,初值为0;定义信号量even表示放偶数单元的个数,初值为0;定义信号量mutex,用于实现缓冲区互斥,初值为1。

P1():

Begin

L1:

x=produce()

p(empty)

p(mutex)

put()

v(mutex)

ifx%2=1thenv(odd)

elsev(even)

gotoL1

end

P2():

Begin

L2:

P(odd)

P(mutex)

Getodd()

v(mutex)

v(empty)

countodd()

gotoL2

end

P3():

Begin

L3:

P(even)

P(mutex)

Geteven()

v(mutex)

v(empty)

counteven()

gotoL3

end

8.过桥者问题,

同方向可上桥,桥上最多可容纳3个人。

过桥问题类似读写者问题,读写者是一方为多个读者,一方为一个写者,而过桥问题相当于把读者分两组,同组的可进入同时阅读。

定义全局变量easten,westen分别表示桥上从东往西和从西往东的人数,初值为0;定义信号量meast,mwest分别用于桥东头和桥西头用于统计人数时进行互斥,初值均为1;桥上无人时两边不能同时上桥,因此定义信号量wait,用于互斥,初值为1;定义信号量count,用于限制桥上人数,初值为3。

以下为桥两端每个过桥者行为的代码:

easttowest():

begin

P(wait)

P(meast)

easten=easten+1

if(easten==1)thenp(mwest)//桥上只要有一个从东往西的,则禁止西桥头的人上桥

v(meast)

v(wait)

p(count)

东->西

V(count)

P(meast)

easten=easten-1

if(easten==0)thenv(mwest)//桥上没有从东往西的人,则允许西桥头的人上桥

v(meast)

end

另一端程序如下,与之类似

westtoeast():

begin

P(wait)

P(mwest)

westen=westen+1

if(westen==1)thenp(meast)

v(mwest)

v(wait)

p(count)

西->东

v(count)

P(mwest

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

当前位置:首页 > 工程科技 > 能源化工

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1