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

之前的Blog基于Queue的生产者消费者模型,已经谈过了基于queue的生产消费模型,其空间是可以动态分配的。而现在是基于固定大小的环形队列重写这个程序。

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

  • 环形队列采用数组模拟,用模运算来模拟环状特性

基于环形队列的生产者消费者模型_第1张图片

  • 环形结构起始状态和结束状态都是一样的,不好判断为空或者为满,所以就需要通过计数器或者标记位来判断满或空。另外也可以预留一个空的位置,作为满的状态。

 

 

  • 消费者总是跟在生产者的后边,且不会超过生产者
  • 生产者一直在消费者的前边,且不会超过消费者一圈。
  • head和tail指向同一个位置的时候,队列为空。
  • 当head在tail的下一个位置时,环形队列为满。

基于环形队列的生产者消费者模型_第2张图片

 

/*#####  ringqueue.cc   ####*/
#include"test.hpp"

const int num=16;

using namespace std;

void *consume_routine(void *arg)
{	
	int d;
	RingQueue *q=(RingQueue*)arg;
	for(;;)
	{
		q->PopData(d);
		cout<<"consume done,data is..."<PushData(d);
		cout<<"Product done,data is..."<
/*******   test.hpp   *******/
#ifndef __TEST_HPP__
#define __TEST_HPP__

#include
#include
#include
#include
#include
#include
#include



class RingQueue
{
private:
	std::vector ring;
	int cap;
	sem_t blank_sem;
	sem_t data_sem;

	int c_step;										//consume在圈中的位置
	int p_step;		  								//product在圈中的位置
private:
	void P(sem_t &sem)
	{
		sem_wait(&sem);
	}
	void V(sem_t &sem)
	{
		sem_post(&sem);
	}
public:
	RingQueue(int cap_):cap(cap_),ring(cap_)
	{
		c_step=p_step=0;							//初始时c_step和p_step在同一格
		sem_init(&blank_sem,0,cap);				//初始时需要写入的输入是整个圈的容量
		sem_init(&data_sem,0,0);					//初始时需要consume的值为0
	}
	void PushData(const int& data)					//进行数据生产
	{
		P(blank_sem);
		ring[p_step]=data;							//把数据放进去
		V(data_sem);
		p_step++;
		p_step%=cap;								//进行模运算来模拟环形特性
	}
	void PopData(int &data  )
	{
		P(data_sem);								//申请数据资源
		data=ring[c_step];							//拿到数据
		V(blank_sem);								//空出格子
		c_step++;
		c_step%=cap;
	}
	~RingQueue()
	{
		sem_destroy(&blank_sem);
		sem_destroy(&data_sem);
	}

};

#endif
******   makefile   ******

ringqueue:ringqueue
	.cc
	g++ -o  $@ $^ -lpthread -fpermissive
.PHONY:clean
clean:
	rm -f ringqueue
	

 

你可能感兴趣的:(Linux)