• (考研)生产者消费者问题(赋代码)


    问题描述

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

    问题分析

    1) 关系分析。生产者和消费者对缓冲区互斥访问是互斥关系,同时生产者和消费者又是一个相互协作的关系,只有生产者生产之后,消费者才能消费,他们也是同步关系。

    2) 整理思路。这里比较简单,只有生产者和消费者两个进程,正好是这两个进程存在着互斥关系和同步关系。那么需要解决的是互斥和同步PV操作的位置。

    3) 信号量设置。信号量mutex作为互斥信号量,它用于控制互斥访问缓冲池,互斥信号量初值为1;信号量full用于记录当前缓冲池中“满”缓冲区数,初值为0。信号量empty 用于记录当前缓冲池中“空”缓冲区数,初值为n

    //PV操作控制进程的那3种基本的状态

    semaphore mutex=1; //临界区互斥信号量,明确一点信号量是像编程语言中的那些普通变量一般,只有PV函数可以对其操作
    semaphore empty=n;  //空闲缓冲区
    semaphore full=0;  //缓冲区初始化为空
    producer ()     //生产者进程
    { while(1)
      { produce an item
    in nextp; //生产数据 P(empty); //获取空缓冲区单元 P(mutex); //进入临界区. add nextp to buffer; //将数据放入缓冲区 V(mutex); //离开临界区,释放互斥信号量 V(full); //满缓冲区数加1 } } consumer () //消费者进程
    {
    while(1)
    { P(full);
    //获取满缓冲区单元 P(mutex); //进入临界区 remove an item from buffer; //从缓冲区中取出数据 V (mutex); //离开临界区,释放互斥信号量 V (empty) ; //空缓冲区数加1 consume the item; //消费数据 } }

    如果生产者进程先执行P(mutex),然后执行P(empty),消费者执行P(mutex),然后执行P(fall),这样可不可以?答案是否定的。设想生产者进程已经将缓冲区放满,消费者进程并没有取产品,即empty = 0,当下次仍然是生产者进程运行时,它先执行P(mutex)封锁信号量,再执行P(empty)时将被阻塞,希望消费者取出产品后将其唤醒。轮到消费者进程运行时,它先执行P(mutex),然而由于生产者进程已经封锁mutex信号量,消费者进程也会被阻塞,这样一来生产者、消费者进程都将阻塞,都指望对方唤醒自己,陷入了无休止的等待。同理,如果消费者进程已经将缓冲区取空,即 full = 0,下次如果还是消费者先运行,也会出现类似的死锁。不过生产者释放信号量时,mutex、full先释放哪一个无所谓,消费者先释放mutex还是empty都可以。

    //生产者进程
  • 相关阅读:
    接口的多实现。
    接口的基本实现。
    构建MVC解决方案(包含哪些项目)
    书目记录
    Chrome浏览器修改user-agent,伪装其他浏览器,附带微信、支付宝user-agent
    [文件]学生信息的简单读入与输出
    scanf高级用法【至此丢弃gets用法 】
    数组,字符串
    [转载]终极解密输入网址按回车到底发生了什么
    typedef 和 #define 的区别
  • 原文地址:https://www.cnblogs.com/cs-lcy/p/7103772.html
Copyright © 2020-2023  润新知