Linux多线程-生产者和消费者

#include <unistd.h>
#include <pthread.h>
#include <errno.h>
#include <iostream>
#include <cstdlib>
#include <string>

using namespace std;

//#define DEBUG

#define VOLATILE volatile
#ifndef VOLATILE
#define VOLATILE
#endif


#define handle_func_ret_val_ne0(func)\
do{if(func!=0) { perror(#func); exit(-1);} } while(0)

class locker
{
public:
	locker ( pthread_mutex_t *mutex):lock(mutex){
		pthread_mutex_lock(lock);
#ifdef DEBUG
		cout<<"have locked!"<<endl;
#endif
	}
	~locker () {
		pthread_mutex_unlock(lock);
#ifdef DEBUG
		cout<<"have unlocked!"<<endl;
#endif
	}
private:
	pthread_mutex_t* lock;
};

class factory
{

public:
	factory()
	:push_pos(0),pop_pos(0),size(0){}

	~factory(){
	}

	int pop(){
		int ret=buffer[pop_pos++];
		if(pop_pos==buffer_size)
			pop_pos=0;
		
		--size;
#ifdef DEBUG
				cout<<"size: "<<size<<'\t';
#endif
		return ret;
	}

	int push(int val){
		buffer[push_pos++]=val;
		if(push_pos==buffer_size)
			push_pos=0;

		++size;
#ifdef DEBUG
				cout<<"size: "<<size<<'\t';
#endif
		return val;
	}

	bool is_full(){
		return size==buffer_size;
	}

	bool is_empty(){
		return size==0;
	}

protected:
	VOLATILE int push_pos;
	VOLATILE int pop_pos;
	VOLATILE int size;
	static const int buffer_size=5;
private:
	int buffer[buffer_size];
};

class factory_manager
{
public:
	factory_manager():
	mutex(PTHREAD_MUTEX_INITIALIZER),
	not_empty(PTHREAD_COND_INITIALIZER),
	not_full(PTHREAD_COND_INITIALIZER){}

	~factory_manager(){	
		pthread_mutex_destroy(&mutex);
		pthread_cond_destroy(&not_empty);
		pthread_cond_destroy(&not_full);
	}

	int put(int val){
		{
			locker lock(&mutex);

			while(ft.is_full()){
#ifdef DEBUG
				cout<<"in put method:factory is full!"<<endl;
#endif
				pthread_cond_wait(&not_full,&mutex);
#ifdef DEBUG
				cout<<"in put method:someone wakes me up!"<<endl;
#endif
			}

			ft.push(val);
		}
		
		pthread_cond_signal(&not_empty);
		return val;
	}

	int get(){
		int val;

		{
			locker lock(&mutex);

			while(ft.is_empty()){
#ifdef DEBUG
				cout<<"in get method:factory is empty!"<<endl;
#endif
				pthread_cond_wait(&not_empty,&mutex);
#ifdef DEBUG
				cout<<"in get method:someone wakes me up!"<<endl;
#endif
			}

			val=ft.pop();
		}

		pthread_cond_signal(&not_full);
		return val;
	}
private:
	pthread_mutex_t mutex;
	pthread_cond_t not_empty;
	pthread_cond_t not_full;

	factory ft;
};

class user
{
public:
	user(const string& n,factory_manager& f):name(n),fm(f){}
	~user(){}

	virtual void run()=0;
	
protected:
	string name;
	factory_manager& fm;
};

class producer:public user
{
public:
	producer(const string& n,factory_manager& f):user(n,f){}
	~producer(){}

	void run(){
#ifdef DEBUG
		cout<<name<<" start runing!"<<endl;
#endif
		srand(time(0));

		for(int i=0;i<10;++i){
			int val=rand();
			fm.put(val);
			cout<<name<<" produced "<<val<<endl;
		}
	}
};

class customer:public user
{
public:
	customer(const string& n,factory_manager& f):user(n,f){}
	~customer(){}

	void run(){
#ifdef DEBUG
		cout<<name<<" start runing!"<<endl;
#endif
		for(int i=0;i<10;++i){
			int val=fm.get();
			cout<<name<<" get "<<val<<endl;
			sleep(1);
		}
	}
};

void* thread_func(void* data)
{
	user* u=(user*)data;
	u->run();
}

int main()
{
	factory_manager manager;

	producer pa("producera",manager);
	producer pb("producerb",manager);

	customer ca("customera",manager);
	customer cb("customerb",manager);

	user* user_table[4]={&pa,&pb,&ca,&cb};
	pthread_t thread_table[4];
	for(int i=0;i<4;++i){
		pthread_create(&thread_table[i],0,thread_func,user_table[i]);
	}

	for(int i=0;i<4;++i){
		pthread_join(thread_table[i],0);
	}
	
	cout<<"done!"<<endl;
}

转载于:https://my.oschina.net/u/1022744/blog/156198

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值