经典进程同步问题解析(附伪代码实现)

文章目录

  • 1 生产者消费者问题
    • 1.1 普通版本
    • 1.2 复杂版本
  • 2 读者-写者问题
  • 3 哲学家进餐问题
  • 4 吸烟者问题
  • 5 理发店问题
    • 5.1 普通版本
  • 6 总结

1 生产者消费者问题

1.1 普通版本

  • 问题描述

一组生产者进程和一组消费者进程共享一个初始为空、固定大小为n的缓存(缓冲区)。生产者的工作是制造一段数据,只有缓冲区没满时,生产者才能把消息放入到缓冲区,否则必须等待,如此反复;同时,只有缓冲区不空时,消费者才能从中取出消息,一次消费一段数据(即将其从缓存中移出),否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,或者一个消费者从中取出消息。

  • 问题分析

    • 关系分析:生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,它们也是同步关系。
    • 整理思路:只有生产者和消费两个进程,正好是这两个进程存在着互斥关系和同步关系,我们需要解决的就是互斥和同步PV操作的位置。
    • 信 量设置:信 量mutex作为互斥信 量,用于控制互斥访问缓冲池,互斥信 量初值为1;信 量full用于记录当前缓冲池中“满”缓冲区数,初值为0;信 量empty用于记录当前缓冲池中“空”缓冲区数,初值为n。
  • 代码实现

    其中,对empty和full信 量的P操作必须放在对mutex信 量的P操作之前。如果生产者进程先执行,然后再执行,假设生产者进程已经将缓冲区放满,此时mutex信 量被封锁,同时生产者进程执行时被阻塞,此时消费者拿不到进入临界区的权限,消费者进程也会阻塞。这样造成死锁。同理消费者进程将缓冲区取空也会产生类似的死锁。

1.2 复杂版本

  • 问题描述

    桌子上有一个盘子,每次只能向其中放入一个水果。爸爸专向盘子中放苹果,妈妈专向盘子中放橘子,儿子专等吃盘子中的橘子,女儿专等吃盘子中的苹果。只有盘子为空时,爸爸或妈妈才可向盘子中放一个水果;仅当盘子中有自己需要的水果时,儿子或女儿可以从盘子中取出。

  • 问题分析

    • 关系分析:由于每次只能向其中放入一个水果可知,爸爸和妈妈时互斥关系。爸爸和女儿、妈妈和儿子是同步关系,而且这两对进程必须连起来,儿子和女儿之间没有互斥和同步关系,因为他们是选择条件执行,不可能并发。

    • 整理思路:这里有四个进程,实际上可以抽象为两个生产者和两个消费者被连接到大小为1的缓冲区上。下图为进程之间的关系。

    • 问题分析

      • 关系分析:5名哲学家与左右邻居对其中间筷子的访问是互斥关系。
      • 整理思路:显然这里有五个进程。本题的关键是如何让一个哲学家拿到左右两个筷子而不造成死锁或者饥饿现象。那么解决方法有两个,一个是让他们同时拿两个筷子;二是对每个哲学家的动作制定规则,避免饥饿或者死锁现象的发生。
      • 信 量设置:定义互斥信 量数组chopstick[5] = {1, 1, 1, 1, 1},用于对5个筷子的互斥访问。哲学家按顺序编 0~4,哲学家i左边的筷子的编 为i,哲学家i右边的筷子的编 为(i+1)%5。
    • 第一种方法:同时拿筷子

      semaphore chopstick[5] = {1, 1, 1, 1, 1};Pi()
      
                                                              

      声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年4月7日
下一篇 2022年4月7日

相关推荐