[进程同步]—生产者与消费者问题

生产者与消费者问题

  • PV操作是用来操作信号量的。

    • P:等待——wait——减法作用——阻塞作用

    • V:释放——signal——加法作用——唤醒作用

    • S.value > 0 :有空闲CPU;

      S.value = 0:CPU刚好用完;

      S.value < 0:进程等待;

      • P操作

      void wait(S)
      {
          S.value--;
          if (S.value < 0)
          {
              加入阻塞队列;
          }
      }
      • V操作

      void signal(S)
      {
          S.value++;
          if (S.value <= 0)
          {
              唤醒阻塞队列第一个进程;
          }
      }
  • 解题思路:

    1.画图理解题目
    2.判断题目类型
    3.分析进程数目,填写进程模板
    4.补充基本代码
    5.补充P,V代码
    6.调整代码
  • 例:爸爸往桌子上每次放一个苹果,儿子每次从桌子上拿一个苹果,放苹果和拿苹果不能同时进行,桌子上最多放10个苹果,用PV操作实现同步互斥。

    • 分析:爸爸——生产者——剩余空间(empty) = 10

      ​ 儿子——消费者——已占用空间(full) = 0

      ​ 信号量S = 1,用来实现互斥。

    • 特征:①容器 ≤ 容量

      ​ ②生产 消费

    • 伪代码

    Dad()
    {
        while(1)
        {
            P(empty);//判断盘子是否已满
            P(S);
            放苹果;
            V(S);
            V(full);//对已占用空间+1
        }
    }
    Son()
    {
        while()
        {
            P(full);//判断盘子是否为空
            P(S);
            取苹果;
            V(S);
            V(empty);//对盘子剩余空间+1
        }
    }
  • 例:桌子上有个盘子,每次只能放一个水果,妈妈放橘子,爸爸放苹果,儿子吃橘子,女儿吃苹果。盘子为空,爸爸或妈妈才能放水果,盘子有水果时,儿子和女儿才能取水果。

    • 分析:

    • 初始值:orange = 0

      apple = 0

      plate = 1

      S = 1

    • 伪代码

      Mom()
      {
          while(1)
          {
              P(plate);
              P(S);
              放橘子;
              V(S);
              V(orange);
          }
      }
      Dad()
      {
          while(1)
          {
              P(plate);
              P(S);
              放苹果;
              V(S);
              V(apple);
          }
      }
      Son()
      {
          while(1)
          {
              P(orange);
              P(S);
              取橘子;
              V(S);
              V(plate);
          }
      }
      Daughter()
      {
          while(1)
          {
              P(apple);
              P(S);
              取苹果;
              V(S);
              V(plate);
          }
      }
      • 操作同一个对象的时候,使用信号量S来实现互斥。

  • [2015—408统考]

    • 有A,B两个人通过信箱辩论,每个人都从自己的信箱取得对方的问题,将答案和新问题组成一个邮件放入对方的信箱中。假设A的信箱可装M封邮件,B的信箱可装N封邮件。初始时A信箱有X封,B信箱有Y封,,辩论者每次只取一封邮件。请用P,V操作实现,并解释信号量的初始值和含义。

      • 分析:生产者A——B的剩余空间

        ​ 生产者B——A的剩余空间

        ​ 消费者A——自己邮箱还有多少封信

        ​ 消费者B——自己邮箱还有多少封信

        full-A:A信箱有多少封邮件

        empty-A:A信箱的容量

        full-B:B信箱有多少封邮件

        empty-B:B信箱的容量

        mutex-A:A信箱的信号量

        mutex-B:B信箱的信号量

      • 初始值:mutex-A = 1,mutex-B = 1

        full-A = x , empty-A = M - X

        full-B = y, empty-B = N - y

      A()
      {
          while(1)
          P(full-A);
          P(mutex-A);
          从自己邮箱取信;
          V(mutex-A);
          V(empty-A);
          读信;
          P(empty-B);
          P(mutex-B);
          向B邮箱投信;
          V(mutex-B);
          V(full-B);
      }
      B()
      {
          while(1)
          P(full-B);
          P(mutex-B);
          从自己邮箱取信;
          V(mutex-B);
          V(empty-B);
          读信;
          P(empty-A);
          P(mutex-A);
          向A邮箱投信;
          V(mutex-A);
          V(full-A);
      }
  • [2014—408统考]

    • 例:系统中有多个生产者和消费者,共享一个能存放1000件产品的环形缓冲区(初始为空)。当缓冲区未满时生产者可放入生产的一个产品,否则等待。当缓冲区未空时,消费者进程可取走一件产品,否则等待。要求一个消费者从缓冲区连续取10件产品后,其他消费者才能取走产品。请用P,V操作实现该流程并解释信号量含义。

      • 分析:生产者(j)—剩余空间

        生产者(i)—剩余空间

        消费者(m)—物件数量

        消费者(n)—物件数量

      • 初始值:empty = 1000;

        full = 0;

        mutex = 1;

        mutex1 = 1;

      j()
      {
          while(1)
          {
              P(empty);
              P(mutex);
              放一件产品;
              V(mutex);
              V(full);
          }
      }
      i()
      {
          while(1)
          {
              P(empty);
              P(mutex);
              放一件产品;
              V(mutex);
              V(full);
          }
      }
      m()
      {
          while(1)
          {
              P(mutex1);
              for(int i = 0;i < 10;i++)
              {
                  P(full);
                  P(mutex);
                  取一件物品;
                  V(mutex);
                  V(empty);
              }
              V(mutex1);
          }
      }
      n()
      {
          while()
          {
              P(mutex1);
              for(int i = 0;i < 10;i++)
              {
                  P(full);
                  P(mutex);
                  取一件物品;
                  V(mutex);
                  V(empty);
              }
              V(mutex1);
          }
      }
      • 上述代码中,mnij的代码一样,所以合并mnij

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值