生产者消费者问题

系统中有一组生产者进程和一组消费者进程,生产者进程每次生产一个产品放入缓冲区,消费者进程每次从缓冲区中取出一个产品并使用。 生产者,消费者共享一个初始化为空,大小为n 的缓冲区。 如何使用信号量机制(P、V操作)实现生产者、消费者进程的这些功能呢? 信号量机制可实现互斥、同步、对一类系统资源的申请和释放。

对于信号量可以看这篇信号量机制

使用信号量解决生产者消费者问题

生产者、消费者共享一个初始为空、大小为n的缓冲区。只有缓冲区没满的时候,生产者才能把产品放入缓冲区,否则必须等待。只有缓冲区不为空的时候,消费者才能从中取出产品,否则必须等待。

缓冲区是临界资源,各个进程必须互斥访问。
首先定义信号量;

semaphore mutex=1; //互斥信号量,实现对缓冲区的互斥访问
semaphore empty=n; //同步信号量,表示空闲缓冲区的数量
semaphore full = 0; //同步信号量,表示产品数量,也是非空缓冲区的数量producer(){while(1){生产一个产品;p(empty);  //小号一个空闲缓冲区p(mutex);  // 实现互斥是在同一进程中进行PV操作把产品放入缓冲区;V(mutex);V(full); //增加一个产品}}
// 实现两个进程的同步,是在其中一个进程中执行P,另一个进程中执行V。consumer(){while(1){P(full); //消耗一个产品P(mutex);从缓冲区取出一个产品V(mutex);V(empty);   //增加一个空闲缓冲区使用产品;}}

管程

为啥要引入管程?

信号量机制存在问题:编写程序困难、易出错。能不能设计一种机制,让程序员写程序时不需要再关注复杂的PV操作,让写代码更加轻松呢?

1973年, Brinch Hansen首次在程序设计语言( Pascal中引入了“管程”成分一一一种高级同步机制)

管程的定义和基本特征

定义

管程是一种特殊的软件模块,由这些部分组成:

  1. 局部于管程的共享数据结构说明;
  2. 对该数据结构进行操作的一组过程(函数)
  3. 对局部于管程的共享数据设置初始值的语句
  4. 管程自己的名字

特征

  1. 管程内的数据只能被管程中定义的函数(过程)访问;(类比于java实体类的get方法)
  2. 一个进程只能通过调用管程内的过称(函数/方法)才能进入管程访问共享数据(进程.getXxx())
  3. 每次仅仅允许一个进程在管程内自行某个内部的过程

用管程解决生产者消费者问题

定义一个管程以下是伪代码

monitor ProducterConsumercondition full,empty;  //条件变量用来实现同步(排队)int count=0; // 缓冲区中的产品数void insert(Item item){//把产品item放入缓冲区if(count == N)wait(full);count++;insert_item(item);if(count == 1)signal(empty);}
Item remove(){ //从缓冲区取出一个产品if(count==0)wait(empty);count--;if(count == N-1)signal(full);return remove_item();
}
end monitor;

生产者进程

producter(){while(1){item = 生产一个产品;ProducterConsumer.insert(item);}
}

消费者进程

consumer(){while(1){item = ProducterConsumer.remove();消费产品;}
}

引入管程的目的无非就是更方便地实现进程的互斥与同步

  1. 需要在管程中定义共享数据
  2. 需要在管程中定义用于访问这些共享数据的“入口”–其实就是一些函数
  3. 只有通过这些函数才能访问管程中的共享数据
  4. 管程中有很多接口,但是每次只能开放其中一个入口,并且只能让一个进程或线程进入,(互斥的特性交给了编译器去实现,程序员不用关心)
  5. 可在管程中设置条件变量级等待/唤醒操作以解决同步问题。

通过管程提供特定的接口来实现进程的同步与互斥,这就是一种封装的思想。

用管程解决生产者消费者问题相关推荐

  1. 【坑】记录型信号量/AND信号量/管程解决生产者-消费者问题

    坑 转载于:https://www.cnblogs.com/wangzhuazhua/p/4771344.html

  2. 管程理解及用管程实现生产者消费者问题

    2.17 管程 管程是一个程序设计语言结构,采用了集中式的进程同步方法,提供了与信号量同样的功能,但更易于控制 概念 由一个共享数据结构(资源的抽象)和为并发进程执行的一组操作组成,这组操作可同步进程 ...

  3. 操作系统课设--使用信号量解决生产者/消费者同步问题

    山东大学操作系统课设lab3 实验三 使用信号量解决生产者/消费者同步问题(lab3) 实验目的 理解Nachos的信号量是如何实现的 生产者/消费者问题是如何用信号量实现的 在Nachos中是如何创 ...

  4. Linux多线程实践(六)使用Posix条件变量解决生产者消费者问题

    前面的一片文章我们已经讲过使用信号量解决生产者消费者问题.那么什么情况下我们须要引入条件变量呢? 这里借用  http://www.cnblogs.com/ngnetboy/p/3521547.htm ...

  5. 两种方式解决 生产者消费者问题

    一.通过wait().notify()线程通信来实现 输出结果: 二.通过阻塞队列来解决生产者消费者问题 输出结果: 由输出结果可以看出:"最后阻塞队列中还剩下4个鸡蛋"明显是正确 ...

  6. JAVA解决生产消费者_Java常用三种方式解决生产者消费者问题(详细)

    package test; /** * Synchronized 版本解决生产者消费者 * wait() / notify()方法 */ import java.util.LinkedList; im ...

  7. 用 wait-notify 写一段代码来解决生产者-消费者问题

    用 wait-notify 写一段代码来解决生产者-消费者问题 参考文章: (1)用 wait-notify 写一段代码来解决生产者-消费者问题 (2)https://www.cnblogs.com/ ...

  8. 如何用管程实现生产者消费者问题?

    文章目录 管程的概念和结构 管程主要特征 管程语法 用管程实现互斥 用管程实现同步 条件变量 管程实现生产者消费者问题 管程的概念和结构 信号量是操作系统提供的一种同步机制,优点是有效.灵活,缺点是容 ...

  9. java信号量生产者_java信号量PV操作 解决生产者-消费者问题

    package test1; /** * 该例子演示生产者和消费者的问题(设只有一个缓存空间.一个消费者和一个生产者) * MySystem类定义了缓冲区个数以及信号量 * @author HYY * ...

最新文章

  1. 需要在Emulator上模拟来电 效果
  2. .net 使用 Aspose.Words 进行 Word替换操作
  3. OpenCASCADE:Genproj tool构建OCCT
  4. oracle 11g-R2安装
  5. 数据结构——二叉树的递归算法
  6. java 实现 常见排序算法(一) 冒泡排序
  7. ListT.Find用法学习
  8. 01 | 基础架构:一条SQL查询语句是如何执行的?笔记(转)
  9. DBA知道这17条Linux命令,就够了!
  10. 将某一类型文件还原为无默认打开方式
  11. STM32F103单片机J-TAG引脚功能关闭方法
  12. python (元祖\列表\集合\字典)基础用法
  13. css学习笔记---盒模型,布局
  14. Java泛型对象的实例化
  15. 深入了解JVM之垃圾回收(二)
  16. 【C语言】写一个斗牛小游戏的发牌器
  17. pc station v15 博图_PC STATION下载报错-工业支持中心-西门子中国
  18. Linux之代理服务器squid安装和使用
  19. 从零到一实现复杂表格需求(antd table 合并行 合并列)
  20. SQL SERVER数据库命名编码规范

热门文章

  1. java 关闭输入密码_为什么不能实现输入密码 3 次错误后不能自动关闭页面
  2. php中session时间,php中session过期时间的设置方法
  3. 成年人必看的六个故事教你学会做人!
  4. An unexpected error has occurred. Conda has prepared the above report. Upload did not complete.
  5. Html5的Canva绘制动态时钟显示当前时间!!!(附源码)
  6. homebrew的基本结构和扩展使用
  7. 如此奇葩,非圆满毕业典礼!个个都是人才
  8. matlab中quat2angle,cord2quat.m
  9. 路由器串联的2种方法
  10. Mac FFmpeg编译和解决nasm/yasm not found or too old错误