题目:

    某寺庙有小和尚和老和尚若干人,水缸一只,由小和尚提水放入水缸给老和尚饮用。水缸可容纳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()原语   不过这种整形信号量并不能解决进程之间让权等待的问题。

      

 

 

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