生产者消费者问题之双缓冲区

今天用两种方法实现了生产者消费者问题。第一种是高效的双缓冲队列,例外一种想法较为复杂,最终效果不如双缓冲队列。

写代码中无意中发现queue是不能用迭代器访问的,而且stack也不可以。

直接上代码如下:

DoubleQueue.h双缓冲队列,其中MutexLock MutexLockGuard见文章多线程读写数据方法之读写锁方法与shared_ptr+互斥锁方法的比较 

#ifndef DOUBLEQUEUE_H_INCLUDED
#define DOUBLEQUEUE_H_INCLUDED

#include
#include
#include
#include
#include
#include
using namespace std;

#include"MutexLock.h"
#include"MutexLockGuard.h"
#include"Condition.h"
#include"MaxSizeQueue.h"

class DoubleQueue{
private:
    vector q1;
    vector q2;//1是写队列2是读队列
    MutexLock mutex1_,mutex_2;
    FILE* file;
public:
    DoubleQueue(){
        file= fopen("out","w");
    }
    void EnQueue(const BufferLog& log){
        MutexLockGuard lock(mutex1_);
        q1.push_back(log);
    }
    bool DeQueue(int done,int all,BufferLog* logs){//单线程写,不对q2的使用加锁了
        if(q2.empty()){
            MutexLockGuard lock(mutex1_);
            q1.swap(q2);
        }
        if(done==all&&q2.empty()){
            fclose(file);
            return true;
        }
        for(vector::iterator p=q2.begin();p!=q2.end();++p){
            fprintf(file,"%d %d\n",(int)p->type,p->cnt);
             logs[(int)p->type-1].cnt+=p->cnt;
        }
        q2.clear();
        return false;
    }
};
#endif // DOUBLEQUEUE_H_INCLUDED
另外一种方法(BlockingQueue+缓冲区)代码,实际上是单缓冲,但临界区也很小

BlockingQueue.h

#ifndef BLOCKINGQUEUE_H_INCLUDED
#define BLOCKINGQUEUE_H_INCLUDED

#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;

#include"MutexLock.h"
#include"MutexLockGuard.h"
#include"Condition.h"
#include"MaxSizeQueue.h"

class BlockingQueue{
private:
    MutexLock mutex_;
    Condition cond_;
     typedef boost::shared_ptr BigBufferptr;
    queue data_;
    MaxSizeQueue maxSizeQueueBuffer;
    ofstream outfile;
    FILE* file;
public:
    BlockingQueue():cond_(mutex_),outfile("out"){
        file= fopen("out","w");
    }
    void EnQueue(const BufferLog& log){
        MutexLockGuard lock(mutex_);
        BigBufferptr tmp;
        if(data_.empty()||data_.back()->Full()){
            tmp=maxSizeQueueBuffer.DeQueue();
            tmp->data_.push_back(log);
            data_.push(tmp);
            cond_.notify();
        }
        else{
            tmp=data_.back();
            tmp->data_.push_back(log);
        }
    }
    bool DeQueue(int done,int all,BufferLog* logs){//单线程写
        BigBufferptr tmp;
        {
            MutexLockGuard lock(mutex_);
            if(done==all&&data_.empty()){
                fclose(file);
                return true;
            }
            while(data_.empty())
                cond_.wait();
            assert(!data_.empty());
            tmp=data_.front();
            data_.pop();
        }
        for(vector::iterator p=tmp->data_.begin();p!=tmp->data_.end();++p){
             fprintf(file,"%d %d\n",(int)p->type,p->cnt);
             logs[(int)p->type-1].cnt+=p->cnt;
            //outfile<<(unsigned int)p->type<<" "<cnt<data_.clear();
        maxSizeQueueBuffer.Enqueue(tmp);
        return false;
    }

};

#endif // BLOCKINGQUEUE_H_INCLUDED
MaxSizeQueue.h

#ifndef MAXSIZEQUEUE_H_INCLUDED
#define MAXSIZEQUEUE_H_INCLUDED

#include
#include
#include
#include
#include
#include
using namespace std;

#include"MutexLock.h"
#include"MutexLockGuard.h"

enum BufferLogType{Type1=1,Type2,Type3,Type4};

typedef struct BufferLog{
    BufferLogType type;
    int cnt;
}BufferLog;

typedef struct BigBuffer{
    const unsigned int Capacity;
    vector data_;
    bool Full(){
        return data_.size()>=Capacity;
    }
    static int cnt;
    BigBuffer():Capacity(1000){
    assert(Capacity!=0);
        data_.reserve(Capacity);
        ++cnt;
    }
    ~BigBuffer(){
        //cout<<"~BigBuffer"<#include
#include
#include
#include
#include
#include

#include"MutexLock.h"
#include"MutexLockGuard.h"
#include"Condition.h"
#include"CountDown.h"
#include"BlockingQueue.h"
#include"DoubleQueue.h"
using namespace std;

BlockingQueue bqueue;//BlockingQueue+缓冲区
//DoubleQueue bqueue;//双缓冲区队列方法
CountDown countdown(4);//四个线程
MutexLock mutex_;
int done=0;

void * bufferFun1(void * arg) {//写线程方法
    int cnt=1600000;//写次数
    BufferLog log;
    for(int i=0;i

你可能感兴趣的:(操作系统,muduo)