操作系统 之 「信号量机制解决进程同步问题」

本文详细探讨了使用信号量解决操作系统中多个经典同步问题的方法,如生产者消费者问题、吸烟者问题、仓库存货问题、多生产者单消费者问题等。分析了各种问题中进程间的互斥与同步关系,并通过信号量的P、V操作实现进程间的协调。通过对各种场景的深入剖析,展示了信号量在解决并发控制问题中的重要作用。
摘要由CSDN通过智能技术生成

经典的信号量同步问题

第一部分 生产者消费者问题

1、多生产者多消费者 – 吃水果

  • 互斥关系

    对缓冲区的访问需要互斥的进行

    消费者与消费者之间为什么有互斥关系呢?因为消费者需要将缓冲区的内容取走,改变了缓冲区的内容。

  • 同步关系

    女儿等待父亲放苹果 儿子等待母亲放橘子

    父亲或母亲等待盘子中的水果被取走 盘子为空才可以放水果 而盘子为空这个事件既可以由儿子触发 也可以由女儿触发 只要触发就可以允许父亲进程和母亲进程放水果

  • 对于缓冲区的个数需要设置同步信号量来标识

    如果缓冲区的数目为1的话,那么同一时刻只会有一个进程访问临界区资源,不会导致互斥问题,有可能不需要设置 互斥信号量 就可以实现 互斥访问缓冲区的功能
    另一个角度:
    同一个时刻只有1个同步信号量的值为1,也就只有一个进程的P操作不会被阻塞,也就实现了进程的互斥

    如果缓冲区大于1的时候,对于多个生产者就需要设置互斥信号量实现互斥的访问临界资源,否则每个生产者进程对临界区的空闲个数进行P操作都可以访问临界区。

  • 分析过程

    • 分析同步问题

      不能从单个进程行为的角度来考虑,而是考虑同步关系事件的先后关系,具体为谁在等待谁释放的什么资源

      对多个消费者 与 多生产者之间的一类(多个)同步关系,并不是每个同步关系对应一个同步信号量, 抽象成 一对事件的先后关系

      比如:

      对单个进程来分析:

      • 儿子取走橘子 导致 父亲可以放苹果

      • 儿子取走橘子 导致 母亲可以放橘子

      • 女儿取走苹果 导致 父亲可以放苹果

      • 女儿取走苹果 导致 母亲可以放橘子

      可以抽象成一对事件的先后关系

      • 取走水果盘子变空事件 导致 放水果事件

      这样就可以使用一个同步信号量来解决问题

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

2、单生产者多消费者问题 – 吸烟者

在这里插入图片描述

在这里插入图片描述

分析

完成信号量初始值为0

生产者在生产某一种组合的时候,没有先去等待抽烟者完成,而是先去准备东西,因为最开始是没有人抽烟的,对完成信号量(初始值为0)进行P操作的话会被阻塞。

因此先进行某种组合的V操作,然后对完成信号量进行P操作等待抽烟者取走,如果有抽烟者在抽烟,就进入等待队列,当完成信号量V之后唤醒。

缓冲区信号量初始值1

对上面的解决也可以采用共享缓冲区的数量作为同步信号量,初始值为1

这样生产者每次生产之前先对缓冲区数量进行P操作,代表桌子上没有空位置了,等待抽烟者抽完,对缓冲区信号量进行V操作「类似上面问题的盘子信号量」

在这里插入图片描述

3、多生产者问题 – 仓库存货物

在这里插入图片描述

分析

  • 进程只有放A产品 进程 和 放B产品进程

  • 关系

    • 互斥:

      每次只能放入一种产品 放A产品和放B产品需要互斥的访问临界资源(仓库)

    • 同步

      这里A放入的时候要考虑 A还能与B是否还能满足数量差(>=0)

      放B之前也要考虑B还能与A容纳的数量差

      设置同步信号量Sa 和 Sb分别代表A 与 B还可容纳的数量差

      放A的进程中

      • 首先要对Sa进行P操作,检查数量差是否还允许A放入

        每次放进去一个A产品,A产品与B产品的数量差就要减一;

      • 当放完之后,要对Sb进行V操作

        为什么呢?

        因为起初A和B产品的数量都是从0开始的,当放入A产品之后,A的产品数量增加了,大于0,受Sa的影响只能放入有限的A产品,然后Sb代表的是相对于A来说允许的差量值,应该是对A现在产品数量再加上Sb的值,但是B产品起初是0,如果B产品放之间对Sb进行P操作,这样只是假设在A产品0件的基础上进行放B产品,因此需要在A产品放入之后,对B与A之间容纳的差量值Sb也要进行V操作,此时Sb变大了,当B产品一直放当追上A产品数量之后,就按照初始的N值进行放B产品,实现相对于A当前数量进行放B产品「在可容纳的差量值之前」

        实际上,B产品在追上A产品数量之前,是由A与B的差量值M控制的「因为此时A已经比B多m-1件了,达到允许的差量最大值,便不再放A,但是B可以放呀,B放之后,对Sa进行V操作,又唤醒了放A产品的进程,因为B产品的放入仓库,导致A与B之间的实际差量值又小于可容纳最大差量值M了,所以A又可以愉快的放入库中了」,追上之后按照B与A的差量值(N)进行控制

解答

在这里插入图片描述

4、多生产者-单消费者问题

在这里插入图片描述
在这里插入图片描述

分析

  • 进程

    这里有三个进程:

    • 生产车间生产A产品并放入F1货架的进程
    • 生产车间生产 B产品并放入F2货架的进程
    • 装配车间分别从货架F1和货架F2上取得A、B零件组装产品进程
  • 关系

    • 互斥

      这里货架属于互斥缓冲区资源,在放入零件和取出零件的时候不允许两个进程同时访问货架临界区资源,防止它们对货架上的同一个位置放零件,这是不允许的。

      因此需要设置mutex对货架进行互斥的访问

    • 同步

      这里放零件A到货架上的进程需要等待组装进程取走货架上的零件而产生的空闲位置
      而组装进程需要等待放零件进程放入货架之后充满一个位置

      因此需要对F1货架的A零件和货架F2的B零件分别设置empty(=10)和full(=0)同步变量来记录货架缓冲区是否为空,是否未满

解答

在这里插入图片描述
20200426100929379

5、自行车生产线 – 解决死锁问题

在这里插入图片描述

分析

这里的问题与前面的多生产者单消费者问题类似,不同的地方在于前面的多生产者生产的东西不是放到同一个缓冲区资源里,因此即使第一个生产者将货架放满了,生产者2还是可以生产放入另一个货架的,这样消费者就可以从各个货架分别取零件然后第一个生产者进程就被唤醒了。

这里是将不同生产者的零件都放到同一个箱子里,这个箱子就是互斥临界资源,当第一个生产者的零件充满临界资源之后就需要等待消费者取走几个零件然后唤醒此进程,但是此时生产者2因为箱子无空间无法生产零件,导致消费者无法取得生产者2生产的零件而被阻塞,这样3个进程权都被堵塞而互相等待,这就产生了死锁。因此不能让某个生产者一直生产零件而占满互斥缓冲区。

  • 进程

    2个生产者进程 1个消费者进程

  • 关系

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值