信号量机制(PV操作)

信号量机制处理互斥关系:

PV操作可以有效地实现对临界区的管理

        设置一个公共信号量s,同时提供两个基于该信号量上的原语操作:P(s)、V(s)

代码实现过程:

P(s)  //检测锁状态并上锁
{
    s--;
    if(s<0)   
    wait(调用p操作的进程);
//wait为阻塞原语,作用是将括号中的进程置于阻塞态
}
V(s) //解锁
{
    s++;
    if(s<=0)
    release(等待队列)
//release为唤醒原语,唤醒一个等待队列中的进程
}

具体实现方式:

        先将信号量s初值置为1(s=1),之后要求每个进入临界区执行的进程执行P操作,离开临界区之前执行V操作,所有试图进入临界区的进程均要求如此。

一个进程执行PV操作的过程:

信号量机制(PV操作)_第1张图片

注:此方式可确保临界区的正确管理

PV操作不仅可以有效管理临界区,还可以管理具体某类资源。设某类资源的数量为n。则设信号量s的初始值为n,执行p操作申请资源,执行V操作释放资源。(执行过程还是如上图所示)

信号量s的取值范围 (s<=n)

  1. s=n,        说明:n个资源可用
  2. 0
  3. s=0,      说明:资源已全部分配,无等待进程
  4. s<0,        说明:|s|个等待进程,n个进程正在使用资源。

信号量机制处理同步关系:

      同步实现的基础是建立在同步多方的沟通交流机制。因为互斥关系处理中涉及到公共信号量s,实际上信号量s也是一种多方的沟通交流机制,故同步关系的处理也可以接触PV操作进行。

与处理互斥关系不同:

1、同步关系的处理的信号量s的初值依据具体问题的初始状态来定,信号量的数量(定多少个s)是由多少个通信方向的数量来定,信号量的大小(S的大小)根据资源的大小而定。

2、P(s)的意义:用来检测对方发送的信息是否到达;V(s)的意义:用来向对方发送信息。

注:默认在初始情况下,Q进程已经向P进程发送了信息。

在下例中,s1=0表示:在初始情况下,P还没有向Q发送信息;s2=1表示:初始情况下,默认Q已经向P发送了信息。

例:缓冲区看作一个资源。

信号量机制(PV操作)_第2张图片

进程实现代码:

//P进程代码
while(1)
{
    ...
   准备字符
    P(s2)//检测Q向P发送的信息是否到达,如果到达则继续执行,反之不执行(挂起)
   向缓冲区输入字符
    V(s1)//向Q发送信息
    ...
}



//Q进程代码
while(1)
{
    P(s1)//检测P向Q发送的信息是否到达
    读出字符并打印字符
    V(s2)//向P发送信息
    ...
}

 信号量处理同步互斥关系:

例子:生产者与消费者问题

问题描述: 

有M个生产者不断生产产品(可以看作一个工厂有M个车间),每个生产者每生产出一个产品均推入产品仓库(每一次只可一个产品入库),仓库最多可放K个产品,有N个消费者(可以看作工厂的代理商)不断从仓库取产品消费,要求每个消费者每次只能取一个产品,且任何时候都只能让一个生产者或消费者进入仓库。对该问题进行同步处理使得产品不会滞销也不会脱销,仓库利用率最大。

问题模型:

信号量机制(PV操作)_第3张图片

解决思路:

     首先明确该问题中生产者们与消费者们之间的并发关系。并发过程中存在互斥关系(生产者与生产者之间;费者与消费者之间互斥访问仓库)和同步关系(生产者与消费者之间的同步关系)。

设仓库为Buff,大小为K,用数组表示,即Buff[K]

生产者与生产者之间,消费者与消费者之间都为互斥使用仓库,因此设一个公共互斥信号S,仓库即为互斥资源,S初值为1,即:S=1。

生产者与消费者之间是同步关系,设生产者向消费者发送的信息为S1,消费者向生产者发送的信息为S2,初始时可认为仓库为空,相当于消费者向生产者发送了信息告诉生产者可以往仓库放K个产品,反过来生产者告诉消费者能从仓库取0个产品,因此,S1=0,S2=K。

 设生产者放产品的位置为in,消费者取产品的位置为out,显然初始时:in=out=0

第i个生产者进程Pi

while(1)

{

    生产产品X;

    P(S);//检查仓库是否有生产者在访问,互斥关系的P操作

  P(S2);//检查消费者的信号是否到达,初始时认为消费者已发送信号给生产者,同步关系的P操作。

   Buff[in]=X;//将产品X放入仓库中in的位置

   in=(in+1)%K;//下一次放产品的位置(因为到了k后,k+1则需要指向Buff[0],通过除k取余的方式)

   V(S);//用完了仓库,则让出仓库,互斥关系的V操作

    V(S1);//通知消费者仓库中新放进了一个产品,同步关系的V的操作

}

第j个消费者进程Cj

while(1)

{

   P(S);//检查仓库是否消费者在使用,互斥关系的P操作

   P(S1);//检测生产者的信号是否到达,初始时认为生产者未发送信号给消费者,同步关系的P操作

    Y=Buff[out];//将产品Y从仓库out的位置取出

    out=(out+1)%K;//下一次取产品的位置

   V(S);//使用完仓库,让出仓库,互斥关系的V操作

    V(S2);//通知生产者仓库中被取走了一个产品,同步关系的V操作

}

注:具有同步和互斥关系中,要先处理同步关系,再处理互斥关系。

你可能感兴趣的:(windows)