如何设计和理解进程同步互斥与P-V操作中的生产者-消费者问题

在计算机中,以进程为单元分配CPU的处理资源,对于单处理器计算机来说,CPU资源是有限的,而待处理的事务(进程)数目是不定的,那这些待处理的进程之间存在什么关系,应该怎么被安排使用CPU资源,也就是下面要讨论的问题。首先,来理解进程间可能存在的这两种关系:
进程互斥:
某几个进程互斥是指这几个进程共享了独占性资源(临界资源)(如CPU、I/O设备),必须协调各进程对资源的使用顺序。
进程同步:
几个进程存在并发关系是指它们为了完成共同任务,需要相互协调运行顺序,比如一个进程在某些关键点上可能需要等待另一个进程完成某个操作,否则就不能进行下去只能等待。

接下来,我们来看信号灯机制这个概念,信号灯在交通中的意义众所周知,那么把信号灯引入到进程中,可用于控制进程的运行过程,通过改变信号灯的状态来阻塞或者唤醒进程。
信号灯变量可定义为一个二元矢量,它的数据结构:
在这里插入图片描述
对信号灯有两个操作,也就是P、V,至于为什么叫P和V这两个名字,查了下:P-通过的意思,V-释放的意思,这两个操作主要针对信号灯数据结构中信号量值和指针队列所做的变化。
P、V两个操作的内容如下:
(以下S—信号量数据结构中信号量值,q—进程PCB队列指针)
P(S,q)
•信号量S值减1;
•若S≥0,该进程继续执行;
•若S<0,该进程阻塞并加入队列q,把CPU使用权交给调度函数。
在这里插入图片描述
V(S,q)
•信号量S值加1;
•若S>0,该进程继续执行;
•若S≤0,该进程继续,并从p队列中唤醒一个进程,使其状态转为就绪。
在这里插入图片描述
概念介绍完毕,当使用P、V操作来解决互斥问题时,实质上是实现进程对独占型共享资源(临界区)的互斥访问,每次只允许最多一个进程处于临界区。那么,P、V操作在互斥问题中的应用如下:
进入临界区之前先执行P操作;(可能阻塞当前进程)
可以把这个操作过程想象成,当你在商场使用公厕时,如果发现有人正在里面,那你就被阻塞了需要排队等待,如果没有人,则你进去使用并且锁上门,以防他人进来。
离开临界区之后再执行V操作;(可能唤醒一个进程)
同样这个过程可以看成,你使用完公厕后,把门打开,释放一个厕所资源,则正在排队等候上厕所的其他人可以按队列顺序来使用厕所。
P、V操作参数S的初始值设置,需要符合具体情况,上厕所的例子可以看出S的初始值应为商场公厕的个数。

用P、V操作来解决同步问题时,实质上就是实现当运行条件不满足时,让进程暂停;当运行条件满足时,让进程继续执行。基本思路如下:
暂停当前进程:关键操作之前,执行P操作;
此处的关键操作,它的发生与否需要依赖其它事件的产生。比如包饺子操作需要依赖剁肉馅事件的完成才能进行,那么在包饺子操作之前,就得执行P操作。
继续进程:关键操作之后,执行V操作;
此处的关键操作,它的发生会影响其它事件能否发生。比如剁肉馅事件完成与否决定能否开始包饺子,那么剁完肉馅后,需要执行V操作。
在同步问题中,P、V操作参数信号量S的值应该要能明确地表示运行条件,上述所示的包饺子剁肉馅事件为同步事件,设置信号量S初始值为0,能够控制包饺子事件的进行与否。

经典同步互斥问题:生产者-消费者问题
一群生产者(Producer)向一群消费者(Consumer)提供产品,共享缓冲区
在这里插入图片描述
m个生产者提供产品放到缓冲区,k个消费者从缓冲区取出产品,缓冲区的大小为5,生产者和消费者共享缓冲区。
分析该问题的规则:
不能向满缓冲区生产产品;
不能从空缓存区消费产品;
每个时间点只允许一个生产者或消费者生产或消费一个产品。
用伪代码描述生产者和消费者:
在这里插入图片描述在这里插入图片描述
根据同步要求:
1.不能向满缓冲区生产产品;
2.不能从空缓冲区消费产品;

分析生产者的关键事件:
“存1个数据到缓冲区”,该事件的发生需要依赖条件“缓冲区没有满”,该事件发生后,缓冲区产品增加1个,为消费者的关键事件“从缓冲区取1个数据”的发生提供了条件。

分析消费者的关键事件:
“从缓冲区取1个数据”,该事件的发生需要依赖条件“缓冲区非空”,该事件发生后,缓冲区产品少1个,为生产者的关键事件“存1个数据到缓冲区”的发生提供了条件。

根据条件1,生产者进程的关键事件“存1个数据到缓冲区”操作之前,应该先判断缓冲区是否已满,所以执行P操作,P操作的信号量值 int empty=5 /信号量:缓冲区的空位个数,初值为5)/
根据条件2,消费者进程的关键事件“从缓冲区取1个数据”操作之前,应该先判断缓冲区是否非空,所以执行P操作,P操作的信号量 int full=0 /信号量:缓冲区的产品个数,初值为0)/

生产者进程的关键事件“存1个数据到缓冲区”执行完后,对消费者的关键事件“从缓冲区取1个数据”产生了影响,所以执行V操作,V操作的信号量为S=full,可以让消费者事件继续进行。
消费者进程的关键事件“从缓冲区取1个数据”执行完后,对生产者的关键事件“存1个数据到缓冲区”产生了影响,所以执行V操作,V操作的信号量为S=empty,可以让生产者事件继续进行。

加上同步关系的P、V操作之后,生产者和消费者的伪代码如下:
在这里插入图片描述在这里插入图片描述

但是还没有完,缓冲区是个共享型独占型资源,根据第三个规则:
每个时间点只允许一个生产者或消费者生产或消费一个产品
缓冲区被每个生产者和消费者互斥使用
生产者之间互斥;
消费者之间互斥;
生产者和消费者之间互斥

那么生产者进程中“存1个数据到缓冲区”事件之前,需要加上互斥的P操作,定义互斥信号量 int mutex=1; /信号量:缓冲区互斥使用,初值1/
事件发生之后,加上互斥信号量的V操作。
同样,消费者进程中“从缓冲区取1个数据”事件之前,需要加上互斥信号量的P操作,事件发生之后,加上互斥信号量的V操作。

加上互斥操作后,生产者和消费者的伪代码如下:
在这里插入图片描述在这里插入图片描述

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值