C++ Thread API的学习之二-生产消费者的实现

这次学习中使用互斥量(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

猜你喜欢

转载自blog.csdn.net/feng973/article/details/79409323