这次学习中使用互斥量(mutex)和条件变量(condition)来实现生产消费者模型。
头文件:
#ifndef PC_HPP
#define PC_HPP
#include <pthread.h>
#include <queue>
#include <stdio.h>
class CCond;
class CLock{
public:
CLock():m_mutex(PTHREAD_MUTEX_INITIALIZER){
}
~CLock(){
pthread_mutex_destroy(&m_mutex);
}
bool lock(){
return (0 == pthread_mutex_lock(&m_mutex));
}
bool unlock(){
return (0 == pthread_mutex_unlock(&m_mutex));
}
friend class CCond;
protected:
pthread_mutex_t m_mutex;
};
class CCond{
public:
CCond():m_cond(PTHREAD_COND_INITIALIZER){
}
~CCond(){
pthread_cond_destroy(&m_cond);
}
bool signal(){
return (0 == pthread_cond_signal(&m_cond));
}
bool wait(CLock& lock){
return (0 == pthread_cond_wait(&m_cond, &lock.m_mutex));
}
bool broadcast(){
return (0 == pthread_cond_broadcast(&m_cond));
}
private:
pthread_cond_t m_cond;
};
//producer
void *producer(void *arg);
//consumer
void *consumer(void *arg);
//worker
void worker();
#endif //PC_HPP
源文件:
#include "producerconsumer.hpp"
using namespace std;
CLock lock;
CCond emptycond;
CCond fullcond;
queue<char> PROD;
void *producer(void *arg)
{
char* threadinfo = (char*)arg;
for(int i=0; i < 100; i++){
lock.lock();
while(PROD.size() >= 10){
printf("%s is waiting for an empty slot...\n", threadinfo);
emptycond.wait(lock);
}
char rprod = 'A' + (i%25);
PROD.push(rprod);
printf("%s put[%d] %c\n", threadinfo, i, rprod);
fullcond.broadcast();
lock.unlock();
}
return NULL;
}
void *consumer(void *arg)
{
char* threadinfo = (char*)arg;
while(true){
lock.lock();
while(PROD.empty()){
printf("%s is waiting for an full slot...\n", threadinfo);
fullcond.wait(lock);
}
printf("%s get %c\n", threadinfo, PROD.front());
PROD.pop();
emptycond.broadcast();
lock.unlock();
}
return NULL;
}
void worker()
{
pthread_t cumer1, cumer2, proc1;
int ret = pthread_create(&cumer1, NULL, consumer, (void*)("Cunsumer1"));
if(0 != ret){
printf("pthread cumer1 create error!\n");
return ;
}
ret = pthread_create(&cumer2, NULL, consumer, (void*)("Cunsumer2"));
if(0 != ret){
printf("pthread cumer2 create error!\n");
return ;
}
ret = pthread_create(&proc1, NULL, producer, (void*)("Producer1"));
if(0 != ret){
printf("pthread proc1 create error!\n");
return ;
}
pthread_join(cumer1, NULL);
pthread_join(cumer2, NULL);
pthread_join(proc1, NULL);
return ;
}
int main()
{
printf("thread test\n");
worker();
printf("test end\n");
return 0;
}
Makefile文件:
all:run
CC=g++
CPPFLAGS=-Wall -std=c++11 -ggdb
LDFLAGS=-pthread
SRC=producerconsumer
SRCPATH=.
run:$(SRCPATH)/$(SRC).o
$(CC) $(LDFLAGS) -o $@ $^
$(SRC).o:$(SRCPATH)/$(SRC).cpp
$(CC) $(CPPFLAGS) -o $@ -c $^
.PHONY:
clean
clean:
rm $(SRCPATH)/*.o run