5.P、V操作和消费者问题 原
时间:2022-06-19
本文章向大家介绍5.P、V操作和消费者问题
原,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
用信号量实现互斥
Var mutex:semaphoer:=1;
Begin
Parbegin
Process1:begin //第一个进程
repeat
wait(mutex);
critical section
signal(mutex);
remainder section
until false;
end;
Process2:begin //第二个进程
repeat
wait(mutex); //申请资源
critical section //使用临界区
singal(mutex); //释放资源
remainder section //剩余区代码
until false;
end
Parend
注意
- 在实现互斥时,wait(mutex)和singal(mutex)必须成对地出现
- 缺wait(mutex)将会引起系统混乱,不能保证对临界资源的互斥访问
- 缺singal(mutex)将会使该临界资源永久不会被释放
经典的同步问题
- 生产者——消费者问题
- 读者——写者问题
- 哲学家进餐问题
生产者——消费者问题
一组生产者进程生产产品给一组消费者进程消费。为使他们并发执行,设一个有n个缓冲区的缓冲池,生产者一次向一个缓冲区中投入消息,消费者从一个缓冲区中取得消息。生产者——消费者问题实际上是相互合作进程关系的一种抽象。
例子
- 在输入时,输入进程是生产者,计算进程是消费者
- 在输出时,计算进程是生产者,打印进程是消费者
制约关系
- 不允许消费者进程到一个空缓冲区中取产品
- 不允许生产者进程到一个已满且还没被取走的缓冲区中投放产品
用记录型信号量解决生产者——消费者问题
- 设有n个缓冲区,每个缓冲区存放一个消息,用互斥信号量mutex对缓冲池实现互斥访问
- 利用资源信号量empty和full分别表示缓冲池中空缓冲区及满缓冲区的数量,又假定这些生产者和消费者相互等效,只要缓冲池未满,生产者便可将消息送入缓冲池;只要缓冲池未空,消费者便可从缓冲池取走一个消息。
var mutex:semaphore:=1;
empty:semaphore:=n;
full:semaphore:=0;
buffer:array[0,1,……,n-1] of item; //生产者生产出来的一个数据就是item
in,out:integer:=0,0; //in记录放入数据的地址,out记录取出数据的地址,其实就是buffer下标
生产者进程:
Procedure:begin
repeat
……
procedure an item nextp; //生产一个数据(下一个)
……
wait(empty); //申请一个空缓冲区,申请成功,empty信号量减1
wait(mutex);
Buffer(in):=nextp; //将nextp放入下标是in的缓冲区中
in:=(in+1) mod n;
singal(mutex); //释放缓冲区
singal(full); //将full信号量加1
until false;
end;
消费者进程
consumer:begin
repeat
wait(full); //申请一个缓冲区
wait(mutex); //含义是判断当前有没有生产者在使用申请的缓冲区
nextc:=Buffer(out);
out:=(out+1) mod n;
singal(mutex);
singal(empty); //释放一个空缓冲区,empty加1
Consumer the item in nextc;
until false;
end;
注意
- 每个程序中互斥的wait(mutex)和singal(mutex)必须成对出现。
- 对资源信号量empty和full的P、V操作成对出现,但它们分别处于不同的程序中。例如P在计算进程中,而V在打印进程中,计算进程若因执行P而阻塞,则以后将由打印进程将它唤醒。
- 每个程序中的P操作顺序不能颠倒。应先执行对资源信号量的P操作,然后再执行对互斥信号量的P操作,否则可能引起进程死锁。
- V操作的顺序无所谓,都可以。
(adsbygoogle = window.adsbygoogle || []).push({});
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- PWN:UnsortedBin Attack
- React、TypeScript、NodeJS 和 MongoDB 搭建 Todo App
- 我想new个对象过七夕,她却抛了异常···
- 在开启了CloudFlare的页面中显示当前节点信息
- MySQL 案例:无主键表引发的同步延迟
- 进入编译器后,一个函数经历了什么?
- Cloudflare中firewall的编写方法
- LeetCode 11盛水最多的容器&12整数转罗马数字
- 刷题一个4ms的程序,代码如何优化到3ms再到2ms?
- 【LeetCode】1. 盛最多水的容器:C#三种解法
- .NET core3.1使用cookie进行身份认证
- User-Agent那些事
- 三分钟Docker-推送本地镜像到仓库
- 初识ABP vNext(6):vue+ABP实现国际化
- MySQL 案例:Delete 删数据后磁盘空间未释放