mutex.h
#ifndef _MUTEX_H_
#define _MUTEX_H_
#include<pthread.h>
#include"condition.h"
class Mutex {
public:
friend class Condition;
Mutex() {
pthread_mutex_init(&pthread_mutex_, NULL);
}
~Mutex() {
pthread_mutex_destroy(&pthread_mutex_);
}
int Lock();
int Unlock();
private:
pthread_mutex_t pthread_mutex_;
};
#endif
mutex.cpp
#include"mutex.h"
inline int Mutex::Lock() {
return pthread_mutex_lock(&pthread_mutex_);
}
inline int Mutex::Unlock() {
return pthread_mutex_unlock(&pthread_mutex_);
}
condition.h
#ifndef _CONDITION_H_
#define _CONDITION_H_
#include <stdint.h>
#include<pthread.h>
#include"mutex.h"
class Mutex;
class Condition {
public:
Condition(){}
Condition(Mutex* mutex){
pthread_cond_init(&condition_, NULL);
is_signaled_ = 0;
mutex_= mutex;
}
~Condition(){
pthread_cond_destroy(&condition_);
}
void Wait(Mutex* mutex);
void Signal();
void BroadCast();
protected:
pthread_cond_t condition_;
int32_t is_signaled_;
private:
Mutex* mutex_;
};
#endif
condition.cpp
#include"condition.h"
inline void Condition::Wait(Mutex* mutex) {
pthread_cond_wait(&condition_, &mutex_->pthread_mutex_);
}
inline void Condition::Signal(){
pthread_cond_signal(&condition_);
}
inline void Condition::BroadCast() {
pthread_cond_broadcast(&condition_);
}
queue.h
#ifndef _QUEUE_H_
#define _QUEUE_H_
#include<iostream>
#include<pthread.h>
#include"mutex.h"
#include"condition.h"
#include"mutex.cpp"
#include"condition.cpp"
class Mutex;
class Condition;
using namespace std;
template <class T>
class Queue {
public:
Queue() {}
Queue(int size , Mutex* m , Condition* c) {
buff = new T[size];
front_ = 0;
tail_ = 0;
number_ = 0;
MaxSize_ = size;
queue_mutex_ = m;
queue_cond_=c;
}
~Queue() {
delete buff;
}
void Enqueue(T& item) {
queue_mutex_->Lock();
while(number_ == MaxSize_) {
// cout<<"queue is full "<<endl;
queue_cond_->Wait(queue_mutex_);
}
buff[tail_] = item;
++tail_;
++number_;
cout<< "producer thread: "<<pthread_self();
cout<<" enqueue......"<<item<<endl;
queue_mutex_->Unlock();
queue_cond_->Signal();
}
void Dequeue() {
queue_mutex_->Lock();
while(number_ == 0){
// cout<<"queue is empty "<<endl;
queue_cond_->Wait(queue_mutex_);
}
T value = buff[front_];
++front_;
--number_;
cout<< "consumer thread: "<<pthread_self();
cout<<" dequeue......"<<value<<endl;
queue_mutex_->Unlock();
queue_cond_->Signal();
}
bool IsEmpty(){
if(number_ == 0)
return true;
else
return false;
}
bool IsFull(){
if(number_ == MaxSize_)
return true;
else
return false;
}
int Size(bool real) {
return number_;
}
private:
int front_;
int tail_;
int number_;
T* buff;
int MaxSize_;
Mutex* queue_mutex_;
Condition* queue_cond_;
};
#endif
threadbase.h
#ifndef _THREADBASE_H_
#define _THREADBASE_H_
#include<pthread.h>
template<class T>
class ThreadBase {
public:
ThreadBase() {}
int Start(pthread_t pthread , const pthread_attr_t* attr = NULL) {
return pthread_create(&pthread, attr , &ThreadBase::DoStart , (void*)this);
}
static void* DoStart(void* param) {
ThreadBase* obj = (ThreadBase*)param;
obj->Run();
return NULL;
}
virtual void Run() {}
private:
pthread_t thread_;
};
#endif
thread.h
#ifndef _THREAD_H_
#define _THREAD_H_
#include<iostream>
#include"threadbase.h"
#include"queue.h"
#include <unistd.h>
using namespace std;
template<class T> class Queue;
template<class T> class Thread;
template<class T>
class Thread : public ThreadBase<T> {
public:
Thread(){}
Thread(Queue<T>* queue ,int flag ,T item ) {
queue_ = queue;
flag_= flag;
item_=item;
}
void Run() {
if(flag_ == 1)
while(1){
sleep(1);
queue_->Enqueue(item_);
}
else
while(1){
sleep(1);
queue_->Dequeue();
}
}
private:
Queue<T>* queue_;
int flag_;
T item_;
};
#endif
producerconsumer.h
#ifndef _PRODUCER_H_
#define _PRODUCER_H_
#include"queue.h"
#include"thread.h"
#include"mutex.h"
#include"condition.h"
#include<iostream>
#include<unistd.h>
#include<pthread.h>
using namespace std;
template<class T>
class ProducerConsumer {
public:
ProducerConsumer(int buff_size ,int producer_number , int consumer_number){
number_producer_= producer_number;
number_consumer_= consumer_number;
mutex_= new Mutex;
cond_= new Condition(mutex_);
queue_= new Queue<T>(buff_size , mutex_ ,cond_);
p1 = new pthread_t[number_producer_];
p2 = new pthread_t[number_consumer_];
}
void Produce(T& item){
Thread<T>* thread1[number_producer_];
for(int i =0 ;i < number_producer_ ;++i){
thread1[i]=new Thread<T>(queue_ ,1 ,item);
thread1[i]->Start(p1[i]);
}
}
void Consume() {
Thread<T>* thread2[number_consumer_];
for(int i =0 ;i < number_consumer_ ;++i){
thread2[i]= new Thread<T>(queue_ ,2 ,arg);
thread2[i]->Start(p2[i]);
}
}
/*
void join(){
for(int i =0 ;i < number_producer_ ;++i)
pthread_join(p1[i] ,NULL);
for(int i =0 ;i < number_consumer_ ;++i)
pthread_join(p2[i] ,NULL);
}
*/
private:
T arg;
int number_producer_;
int number_consumer_;
Mutex* mutex_;
Condition* cond_;
Queue<T>* queue_;
pthread_t* p1;
pthread_t* p2;
};
#endif
main.cpp
#include"producerconsumer.h"
#include<pthread.h>
#include <unistd.h>
#include<string>
#include<stdlib.h>
int main() {
string item ="apple";
///缓冲区大小设为150,3个生产者,3个消费者
ProducerConsumer<string>* procon = new ProducerConsumer<string>(150 ,3, 3);
procon->Produce(item);
procon->Consume();
sleep(10000);
return 0;
}