题目:
某寺庙有小和尚和老和尚若干人,水缸一只,由小和尚提水放入水缸给老和尚饮用。水缸可容纳12桶水,水取自同一口水井,水晶井口直径窄,每次只能容纳一只水桶取水,水桶总数为4个。每次小和尚只能往水缸里放入1通水,老和尚每次只能取出1桶水,并且小和尚放水和老和尚去睡不能同时进行。
用 P V 原语写出小和尚和老和尚入水、取水的活动过程(可能有人忘记了什么是P V原语,我在文末写了点提示。可以看看)
先审题:
水缸一只: 说明这里是互斥的。我们可以记为 mutex-vat = 1;
小和尚提水给老和尚饮用 :说明了一个流程 ; 小和尚——>老和尚
水缸可容纳12桶水: 作为制约老和尚或者小和尚进程什么时候可以执行的条件。也是两个进程之间的联系。 即两个进程的同步性
同一口水井: 这里也是互斥的,记为:mutex-well;
水桶总数为4: 表示这种资源数量 记为:pail = 4;
题中最后一句话,就表明:放水和取水是互斥的。
整理下审题结果:
mutex-vat = 1;//水缸 mutex-well = 1; //水井 pail = 4;//水桶
再看题目 “ 用 P V 原语写出小和尚和老和尚入水、取水的活动过程” 可以知道其实在需要写两个进程。
小和尚进程:拿桶——从水井打水——放水到水缸——放回桶
老和尚进程:拿桶——从水缸打水(包括喝水)——放回桶
在写进程之前,可以再想一想,是否还需要什么变量或者我们题目中哪个变量还没有用到,使得这两个进程可以并发进行。
比如说:小和尚放水之前是不是应该判断“水缸是否需要放水”
老和尚喝水之前是不是也应该判断“水缸是否有水”。
所以我们可以再加以下两个变量
Temp = 12 ; //表示水缸里还可以放几桶水;
Full = 0; //水缸里现在有几桶水。老和尚能不能喝。
开始写程序://有一点要注意: P v原语应该是一一对应的。 Project 小和尚() { While(1) { P(Temp); P(pail); P(mutex-well); 打水; V(mutex-well); P(mutex-vat); 放水; V(mutex-vat); V(pail); V(full); } }
Project 老和尚() { While(1) { P(full); P(pail): P(mutex-vat); 喝水; V(mutex-vat); V(pail); V(Temp); } }
做这种题大概思路如下:
1:确定同步/互斥关系; 同步:设置初值为0的同步信号 互斥:设置初值为1的互斥信号量
2:根据各进程的操作流程,确定P V 操作的大致顺序。
3:实现互斥操作是同一进程中使用一对P V操作 ,而同步操作是在其中一个进程中执行P;另一个进程中执行V;
如上面所提到的: 小和尚进程中对于水井的使用, P(mutex-well);打水;V(mutex-well);就是在同一进程中使用。
而对于 水缸中的水还有多少: 就是分为小和尚进程中执行:P(temp)在老和尚进程中执行:v(temp)
4:再补充一点 我们在寻找同步关系是,并不是针对某两个进程之间的同步关系,而是某两个事件之间的同步关系。
P V原语是什么?
简单来说就是: p()给这个资源-1,如果没资源就让这个进程进入阻塞队列。
v()给这个资源+1,如果有资源了,就唤醒这个阻塞队列的第一个进程。 这里是结构体信号量
代码如下:其中wait就是P()原语 : signal 就是v()原语 不过这种整形信号量并不能解决进程之间让权等待的问题。

个人能力有限,还请大家多多指正。