zoukankan      html  css  js  c++  java
  • 002. 生产者与消费者-记录型信号量

    -----------------------------

      - 涉及内容:
    
      - 2020/10/30
    

      - 识记生产者与消费者特征:
      
      - 1. 具有容器
    
      - 2. 生产者会使容器容量变小(将数据存放到容器中,使得容器容量变小)
    
      - 3. 消费者会使容器容量变大(将容器中的数据取出来,使得容器容量变大)
    

    经典问题

    题目如下:

    有两个进程:生产者进程和消费者进程共享一个初始为空、固定大小为 n 缓冲区,只有缓冲区没满时,生产者才能把消息放入到缓冲区,
    否则必须等待。同时,只有缓冲区不空时,消费者才能从中取出消息,否则必须等待。由于缓冲区是临界资源,它只允许一个生产者放入消息,
    或者一个消费者从中取出消息。

          - 应该了解内容:
    
          - 适用条件:进程间共享一个临界资源,共享多个的话可能会产生死锁问题
          
          - 同步关系:进程之间存在依赖关系,即一个进程的执行需要依赖与其他进程的消息或者信号,从而唤醒该进程
          - 互斥关系:进程之间共享资源,但同一时刻只能有一个进程能够获取到资源,其他进程则需等待
          - p : 表示申请一个资源
          - v : 表示释放一个资源
    
          - 记录型信号量:各进程之间共享一个临界资源,当需要访问多个临界资源的时候,可能会引起死锁问题
    
    
          - 析:生产者和消费者对于缓冲区的访问属于互斥关系,即缓冲区一次只能有一个进程在访问。同时,必须在生产者放入消息之后,
              消费者才能取出消息,彼此之间存在依赖关系,所以,两者也属于同步关系。    
    
          - 思路流程:
                producer:
                      1. 先要有一个消息
                      2. 判断缓冲区是否还有剩余空间 p(empty)
                      3. 判断缓冲区是否被占用,空闲则进,被占用则等待 p(mutex)
                      4. 空闲情况下,将消息放入缓冲区 
                      5. 离开缓冲区,并且释放互斥信号量  v(mutex)
                      6. 缓冲区被中占用空间 + 1   v(full)
                      7. 注意点:2,3步骤顺序不能调换,不然可能陷入阻塞状态
                consumer:
                      1. 判断是否有消息可取,即看缓冲区是否有空间被占用  p(full)
                      2. 判断缓冲区是否被占用,空闲则进,被占用则等待 p(mutex)
                      3. 空闲情况下,将消息从缓冲区中取出
                      4. 离开缓冲区,并且释放互斥信号量  v(mutex)
                      5. 缓冲区空闲空间 +1    v(empty)
                      6. 使用该消息
                      7. 注意点:1,2步骤顺序不能调换,不然可能陷入阻塞状态
    
          新补充:上面的思路是过程,"判断"是为了理解,并非体现在代码中,属于学习弯路
          新理解:在写一个进程时,不必过多地考虑另一个进程,只专注于当前进程要完成的任务即可
          ------------------------------------------------------------------------------------------------------------------
    
    
          - 参数说明:
    
          - mutex:互斥信号量,表示当前缓冲区状态,mutex = 1 即为缓冲区未被占用
    
          - empty:缓冲区容量信号量,表示当前缓冲区内空余的空间,初始值 empty = n ,表示当前缓冲区还有 n 个空余空间
    
          - full:缓冲区容量信号量,表示当前缓冲区内已被占用的空间,初始值 full = 0 ,表示当前缓冲区尚未存放消息      
    
          - buffer:缓冲区
    
    
    semaphore mutex = 1 , empty = n , full = 0;
    
    producer(){
          while(1) {
                producer an item in nextc;
                p(empty);
                p(mutex);
                put nextc to buffer;
                v(mutex);
                v(full);
          }
    }
    
    consumer () {
          while(1) {
                p(full);
                p(mutex);
                take an item from buffer;
                v(mutex);
                v(empty);
                consume the item;
          }
    }
    
    
    to be continued...
    --------------------
    
    不断修正,不断笔记,能力有限,若有不妥之处,望不吝指教。
    --------------------------------------------------------
    

  • 相关阅读:
    Linux unalias命令 取消别名
    linux cp 拷贝文件或目录
    POJ 1850
    POJ 1844
    POJ 1852
    POJ 1837
    POJ 1833
    POJ 1804
    POJ 1789
    POJ 1781
  • 原文地址:https://www.cnblogs.com/cstrick-1/p/13901663.html
Copyright © 2011-2022 走看看