操作系统:小和尚打水+老和尚喝水经典同步问题实现 菜鸟的解题全过程(附具体代码)

操作系统刚上两周网课老师便布置了两道现阶段本人觉得是课设的”课设“,第一道题在之前的博客中报告过了,下面是第2道题的菜鸟报告。上一篇博客中有初次做这道题的具体分析过程了,这里就侧重后面的代码实现部分的分析。

先上题目:

题目

某寺庙,有小和尚、老和尚若干。有一水缸,由小和尚提水入缸,老和尚从缸中取水饮用。水缸可容纳10桶水,水取自同一水井中,水井径窄,每次只能容一个水桶取水。水桶总数为3个,每次入、取缸水仅为1桶,且不可同时进行。试给出取水、入水的算法描述。

1、初解

1、乍一看以为只是算法描述,然后课本和一些网上资源也只是P、V操作的伪代码。因此我的分析是这样子的:
看题过程把重点信息找出来(即找出资源),然后开始进一步捋清流程。
小和尚打水入缸流程:
拿桶--------->去水井取水(互斥,P、V操作)--------->把水倒入水缸(互斥,P、V操作)--------->放桶
老和尚取水饮用流程:
拿桶--------->去水缸取水(互斥,P、V操作)--------->放桶
2、伪代码如下:

semaphore  mutex_well = 1, mutex_vat = 1;//互斥量
semaphore  pail = 3, empty = 10, full = 0;//定义自然量,empty表示水的总容量,full表示满的标志
project  small()//小和尚
{
   
 while (true)
 {
   
  P(empty); //判断水缸是否还有容量,有则减一,程序向下执行
  P(pail);  //申请一个桶
  P(mutex_well);  //占用水井
  从水井中打水;  //活动
  V(mutex_well); //用完水井,释放资源
  P(mutex_vat);  //占用水缸
  将水倒入水缸中; //活动
  V(mutex_vat)  //释放资源
  V(pail);   //放桶
  V(full);  //full+1,即水缸中的水的桶数加1,注意成对出现问题!!!
 }
}
project old()//老和尚
{
   
 while (true)
 {
   
  P(full); //看是否有水,有则减一,程序向下执行
  P(pail); //拿桶
  P(mutex_vat); //占用水缸
  从水缸中取水; //活动
  V(mutex_vat); //用完水缸,释放资源
  喝水; //此处虽可省,但有这一步更为具体形象
  V(pail); //放桶
  V(empty); //容量加一,可装入的水的桶数加1
 }
}

通过看课本和在网上看一些别人的总结分享,我写出了这段伪代码。写完后心里还想着,咦,老师不是说比上次的题目困难很多吗?怎么这么容易就被我搞定了(是真的比较容易,只要求这样子的答案的话)。但,无论如何当时都觉得很开心,终于把这个每周都会有的令人担忧的操作系统实操作业搞定了!(毕竟我比较菜鸟)

2、再次上课

很多人都只是写了简单的一段伪代码,毕竟题目只是说算法描述,老师也没特别说明,就只是说回去把它搞好,So…
然后就被说了:”伪代码有啥可看的”,然后便"耐心“地讲解了关于这方面的内容,主要就是信号量的具体使用吧,下课前留了一句:回去接着把题目搞好啊…
课上老师讲解了一个简单的示例,如下:


                
  • 29
    点赞
  • 100
    收藏
    觉得还不错? 一键收藏
  • 7
    评论
和尚打水问题是一个经典操作系统进程同步问题,它的场景如下:有一群小和尚需要到井里打水,井边有一个水桶,水桶只够一个人打满,当有两个或多个小和尚同时到达水桶时,需要一定的协调机制来保证他们不会互相干扰,进而导致打水失败或者浪费时间。 这个问题可以用生产者-消费者问题来进行描述。其中,小和尚充当生产者角色,而水桶充当消费者角色。具体来说,小和尚从井里打出的水相当于生产者生产的物品,而水桶相当于消费者消费的物品。当水桶为空时,小和尚需要等待,直到有水桶被填满;而当水桶已经被填满时,小和尚需要等待,直到有空闲的水桶。 为了解决这个问题,我们可以采用经典的信号量机制。具体来说,我们可以定义两个信号量:一个表示水桶中的水的数量,另一个表示空闲的水桶的数量。当一个小和尚需要打水时,它需要首先检查空闲的水桶的数量是否大于0,如果大于0,则将该信号量减1,表示占用了一个水桶;接着,它需要检查水桶中的水的数量是否为0,如果为0,则需要等待,直到有水桶被填满;最后,它将水桶中的水的数量减1,表示打出了一份水,并释放该水桶。 下面是一个简单的伪代码示例: ``` Semaphore mutex = 1; // 互斥信号量 Semaphore full = 0; // 水桶中的水的数量 Semaphore empty = N; // 空闲的水桶的数量 void monk() { while (true) { wait(empty); // 等待空闲的水桶 wait(mutex); // 进入临界区 if (full == 0) { // 如果水桶中的水的数量为0,则需要等待 signal(mutex); // 退出临界区 continue; } // 打出一份水 full--; signal(mutex); // 退出临界区 signal(empty); // 释放水桶 } } ``` 在这个示例中,我们使用了三个信号量:`mutex`表示互斥信号量,用于保证同一时间只有一个小和尚能够占用水桶;`full`表示水桶中的水的数量,用于标识水桶是否已经被填满;`empty`表示空闲的水桶的数量,用于标识是否有可用的水桶。 当一个小和尚需要打水时,它首先等待空闲的水桶,然后进入临界区,检查水桶中的水的数量是否为0。如果为0,则说明水桶还没有被填满,需要释放互斥信号量并重新等待;否则,打出一份水,将`full`减1并释放互斥信号量和空闲的水桶。 通过这种机制,可以保证在任何时刻只有一个小和尚能够占用水桶,并且只有在水桶被填满后才能够打出水来。这样就能够避免多个小和尚同时打水的情况,从而提高了效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值