`
bcyy
  • 浏览: 1826350 次
文章分类
社区版块
存档分类
最新评论

生产者消费者模式C++程序模拟实现

 
阅读更多

关于生产者和消费者的分析可以参考:

http://blog.csdn.net/kenden23/article/details/16340673

这里是利用C++简单模拟一个生产者消费者的工作模式。没有考虑到同步问题。

操作了一个队列,用BUFFER_SIZE控制了队列的大小,也根据需要可以不用控制大小。感觉数据结构无处不在。

使用单一设计模式实现缓冲区。

执行类代码:

#ifndef PRODUCERCONSUMER_H
#define PRODUCERCONSUMER_H

#include<string>
#include<queue>

using std::string;
using std::queue;

class Buffer
{
	//不能用const,需要加上static,否则vs无法编译
	const static int BUFFER_SIZE = 10;
	queue<string> bMemory;
	static Buffer *singleBuffer;

	//若这里定义了构造函数,就算是空,也必须要到.cpp文件定义。要么都不写。单一模式一定要写
	Buffer();

public:
	//这里的static最容易忘记,一定要记得。
	//非静态成员引用一定要与特定对象相对,否则编译错误。
	static Buffer *getBuffer();

	string top() const
	{
		return bMemory.front();
	}
	string buttom() const
	{
		return bMemory.back();
	}

	int size() const
	{
		return bMemory.size();
	}

	bool empty()
	{
		return bMemory.empty();
	}

	bool full()
	{
		return bMemory.size() == BUFFER_SIZE;
	}

	bool push(string &str)
	{
		if(!full())
		{
			bMemory.push(str);
			return true;
		}
		return false;
	}

	bool getAndPop(string &str)
	{
		if(!empty())
		{
			str = bMemory.front();
			bMemory.pop();
			return true;
		}
		return false;
	}

	~Buffer()
	{
		if(singleBuffer)
			delete singleBuffer;
	}
};

//===============================================================
class ProducerConsumer
{
public:
	ProducerConsumer();
	//~ProducerConsumer();

	void produce(string prostr);
	void consume(string &constr);
	void wait();
	void whatInPool();

private:
	Buffer *shaderdMemory;
};

#endif


头文件:

#include<iostream>
#include"ProducerConsumer.h"

using namespace std;
//注意:类里面的static成员不过是声明,如果没有定义的话,那么就无法使用的,在cpp里面才能定义,就是分配内存空间。
Buffer *Buffer::singleBuffer = nullptr;

//这个函数需要使用singleBuffer,如果没有上面的定义的话,就会出现错误:无法解析的外部符号
//原因就是singleBuffer还没有定义,当然是无法使用这个符号。
Buffer *Buffer::getBuffer()
{
	if(!singleBuffer)
	{
		singleBuffer = new Buffer();
	}
	return singleBuffer;
}
Buffer::Buffer()
{
}
ProducerConsumer::ProducerConsumer()
{
	shaderdMemory = Buffer::getBuffer();
}

void ProducerConsumer::produce(string prostr)
{
	//如果没有下面的函数定义,那么下面的wait()也是无法使用的,无法解析外部符号。
	//也是因为有声明没有定义的缘故。类里面的函数也是相当于声明。所以必须定义了之后才能使用。
	if(!shaderdMemory->push(prostr))
	{
		wait();
		return;
	}
	cout<<"Good! We have produced one item.\n";
}

void ProducerConsumer::consume(string &constr)
{
	if(!shaderdMemory->getAndPop(constr))
	{
		wait();
		return;
	}
	cout<<"Very well! you just consume "<<constr<<" successfully\n";
}

void ProducerConsumer::wait()
{
	cout<<"The Buffer is full, or you comsume too much.\n"
		<<"You need to produce some or comsume some first and come back try again.\n";
}

void ProducerConsumer::whatInPool()
{
	string temp;
	cout<<"We have "<<shaderdMemory->size()<<" in our pool.\n";
	for (int i = 0; i < shaderdMemory->size(); i++)
	{
		if(!shaderdMemory->getAndPop(temp)) 
		{
			cerr<<"Empty\n";
			return;
		}
		cout<<temp<<"\n";
		shaderdMemory->push(temp);
	}
	cout<<endl;
}


测试主程序:

#include<iostream>
#include<vector>
#include<algorithm>
#include"ProducerConsumer.h"

using namespace std;

int main()
{
	string item;
	ProducerConsumer prodcons;
	char ch;

	cout<<"Produce or Consume or Leave?(p or c or l)"<<endl;
	ch = getchar();
	while (ch != 'l')
	{
		switch (ch)
		{
		case 'p':
			cout<<"What do you want to produce? Name it, we will make it for you!"<<endl;
			//如果是用cin那么空格之后的字符就不能读入,getline可以读入任意多的字符
			//注意:清楚数据流中的\n回车字符
			while (getchar() != '\n');
			getline(cin, item);
			prodcons.produce(item);
			cout<<"Produce or Consume or Leave?(p or c or l)"<<endl;
			ch = getchar();
			break;
		case 'c':
			cout<<"Welcome, consumer!"<<endl;
			prodcons.consume(item);
			cout<<"Produce or Consume or Leave?(p or c or l)"<<endl;
			while (getchar() != '\n');
			ch = getchar();
			break;
		default:
			cout<<"Produce or Consume or Leave?(p or c or l)"<<endl;
			while (getchar() != '\n');
			ch = getchar();
			break;
		}		
	}

	cout<<"See what we have produced in pool\n";
	
	prodcons.whatInPool();
	
	system("pause");
	return 0;
}


最终运行结构:

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics