Linux:生产者消费者模型下篇(基于环形队列)

基于环形队列的生产者消费者模型

上篇讲解了生产者消费者模型以及基于BlockingQueue实现该模型,下篇这里就实现一个基于环形队列的生产者消费者模型吧!这个环形队列用数组来实现。

1.如何把数组设置一个环形的队列呢?
利用模运算来实现顺序结构的环形操作。0 ~ 9模10依然是0 ~ 9,10模10就变成0了,也就回到了数组的头部,从而实现一个环形队列。

2.那么如何判断该环形队列的空和满呢?
刚开始的时候生产者和消费者指向同一块空间,生产者在生产的时候,先判断前面的格子里是不是消费者,如果前面的格子里不是消费者就在当前格子里生产数据,然后++,如果前面的格子里是消费者,那就不在当前的格子里生产数据,保持不动。
假如现在有10个格子,下标为0 ~ 9,消费者依然在0号格子,生产者生产到8号格子了,那么生产者判断9号格子不是消费者,于是在8号格子里生产数据,然后++到9号格子,此时继续判断,生产者发现9号格子的下一个0号格子里是消费者,所以此时生产者不再生产,表示该环形队列已经满了。所以我们采用浪费一个格子的操作实现了判空和判满。

3.四条规则

  1. 消费者不能超过生产者(如果消费者快,但是生产者还没生产完的时候,消费者就不能进行消费,消费者必须等生产者生产完)
  2. 生产者不能把消费者套一个圈(如果生产者快,而且队列已经被生产者生产满了,此时生产者就不能进行生产了,生产者此时就必须等消费者消费完才能继续生产)
  3. 环形队列为空的时候,生产者先出发
  4. 环形队列为满的时候,消费者先出发

4.怎么实现?
引入两个信号量,一个记录格子资源个数,另一个记录数据资源个数。
生产者生产的时候要申请空格子(P格子:格子资源数减一),那么生产完毕之后有数据的格子就会多一个(V数据:数据资源数加一)。
消费者消费的时候就是要拿取有数据的格子(P数据:数据资源数减一),那么消费完毕之后空格子就会多一个(V格子:格子资源数加一)

具体实现代码解释:
在这里插入图片描述
运行结果:
此时生产者生产的快,因此会迅速把环形队列生产满,满了之后基于信号量的同步和互斥它就不能生产了,因此消费者开始每隔一秒消费一条数据,当消费者消费完一条数据之后,格子信号量就会增加1,因此生产者又会快马加鞭的生产一条数据,消费者再隔一秒消费一条数据,生产者还是穷追不舍的又生产一条数据,因此看到的结果是生产者迅速生产满之后,就变成了消费一条生产一条。
在这里插入图片描述
代码如下:

  1 #include <iostream>
  2 #include <pthread.h>
  3 #include <stdlib.h>
  4 #include <time.h>
  5 #include <semaphore.h>
  6 #include <unistd.h>
  7 #define NUM 16
  8 class ring{
   
  9     private:
 10         int Ring[NUM];
 11         sem_t blank_sem;
 12         sem_t data_sem;
 13         int
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值