• OS2.3.6:生产者,消费者问题


    0 问题描述

    系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据)

    生产者和消费者是共享一个初始为空、大小为n的缓冲区的。

    在这里插入图片描述
    刚开始缓冲区是空的,所以生产者可以往缓冲区中放入产品。
    在这里插入图片描述
    当缓冲区放满了之后,生产者就不能往里放数据了,此时只能让消费者取走产品,生产者才能继续将产品放入。

    缓冲区是临界资源,各进程必须互斥地访问。

    假如系统当中有两个生产者进程,两个生产者进程发现缓冲区当中的位置都是空的,由于并发性,两个生产者进程很有可能都瞄准了同一个缓冲区当中的块。所以由于这个特性,所以缓冲区必须是被互斥的进行访问的。
    在这里插入图片描述

    1 问题分析

    系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。(注:这里的“产品”理解为某种数据)
    生产者、消费者共享一个初始为空、大小为的缓冲区。

    • 只有缓冲区没满时,生产者才能把产品放入缓冲区,否则必须等待。(同步)
    • 只有缓冲区不空时,消费者才能从中取出产品,否则必须等待。(同步)
    • 缓冲区是临界资源,各进程必须互斥地访问。(互斥)

    Q:如何使用信号量机制(P,V操作)实现生产者、消费者进程的这些功能呢?
    A:信号量机制可以实现互斥、同步、对一类系统资源的申请和释放。

    关于互斥的实现:

    • 设置初值为1的互斥信号量

    关于同步的实现:

    • 设置初值为0的同步信号量(实现“一前一后”)

    关于对同一类系统资源的申请和释放

    • 设置一个信号量,初始值即为资源的数量,本质上也属于“同步问题”,若无空闲资源,则申请资源的进程需要等待别的进程释放资源后才能继续往下执行。

    所以,上一节的问题,都可以归类于互斥、同步的问题。

    PV操作题目分析步骤:

    1. 关系分析。找出题目中描述的各个进程,分析它们之间的同步
    2. 整理思路。根据各进程的操作流程确定P、V操作的大致顺序。

    生产者每次要消耗§一个空闲缓冲区,并生产(V)一个产品。消费者每次要消杌§一个产品,并释放一个空闲缓冲区(V)往缓冲区放入/取走产品需要互斥。

    在这里插入图片描述

    2 实现

    生产者将产品放入缓冲区,消费者从缓冲区取走产品。
    在这里插入图片描述
    实现互斥是在同一进程中进行一对PV操作;实现两进程的同步
    关系,是在其中一个进程中执行P,另进程中执行V。

    3 能否改变相邻P,V操作的顺序?

    在这里插入图片描述

    若此时缓冲区内己经放满产品,则empty=0,full=n。
    则生产者进程执行①使mutex? 变为0,再执行②,由于己没有空闲缓冲区,因此生产者被阻塞。
    由于生产者阻塞,因此切换回消费者进程。消费者进程执行③,由于utex为0,即生产者还没
    释放对临界资源的“锁”,因此消费者也被阻塞。
    这就造成了生产者等待消费者释放空闲缓冲区,而消费者又等待生产者释放临界区的情况,生产者和消费者循环等待被对方唤醒,出现“死锁”。同样的,若缓冲区中没有产品,即full=0,empty=n。按③④①的顺序执行就会发生死锁。因此,实现互斥的P操作一定要在实现同步的P操作之后。V操作不会导致进程阻塞,因此两个V操作顺序可以交换。

    综上,实现互斥的P操作要放到实现同步的P操作之后。V操作可以交换,不会导致阻塞。

    4 总结

    在这里插入图片描述

  • 相关阅读:
    proxysql-安装部署
    Python中return和yield的区别
    五、stm32-SysTick(系统定时器)
    MySQL源码解析之执行计划
    游戏:逢7过
    【ESP32】Arduino C语言语法总结
    视频转序列图片:高效批量转换,释放创造力
    二进制编码及浮点数表示
    数据结构-----堆(完全二叉树)
    SpringBoot Web开发----请求参数处理
  • 原文地址:https://blog.csdn.net/weixin_44673253/article/details/126322287