基于阻塞队列(条件变量 + 锁)的生产者消费者模型

基于阻塞队列(条件变量 + 锁)的生产者消费者模型

BlockQueue.hpp (阻塞队列)

c++ 复制代码
#include <iostream>
#include <cstdlib>
#include <unistd.h>
#include <vector>
#include <queue>
#include "sem.hpp"
#include "Mutex.hpp"
#include "Cond.hpp"
using namespace std;

#define BLOCKQUEUESIZE 5
template <class T>
class BlockQueue
{
public:
    BlockQueue(int num = BLOCKQUEUESIZE)
    :num_(num)
    {}
    void push(const T& in)
    {
        T t = in;
        lock_Guard mtx(mtx_);
        if(isFull())
            cv_space_.Wait(mtx);
        block_queue_.push(t);
        cv_data_.notify_one();
    }
    T pop()
    {
        lock_Guard mtx(mtx_);
        if(isEmpyt())
            cv_data_.Wait(mtx);
        T t = block_queue_.front();
        block_queue_.pop();
        cv_space_.notify_one();
        return t;
    }
    bool isEmpyt() {return block_queue_.empty();}
    bool isFull() {return block_queue_.size() == num_;}
private:
    queue<T> block_queue_;
    int num_;
    Mutex mtx_;
    Condition_variable cv_data_;
    Condition_variable cv_space_;
};

Cond.hpp (封装条件变量)

c++ 复制代码
#include <iostream>
#include <cstdlib>
#include "Mutex.hpp"
class Condition_variable
{
public:
    Condition_variable()
    {
        pthread_cond_init(&cond_,nullptr);
    }
    void Wait(lock_Guard& lg)
    {
        pthread_cond_wait(&cond_,lg.getMutex());
    }
    void notify_one()
    {
        pthread_cond_signal(&cond_);
    }
    void notify_all()
    {
        pthread_cond_broadcast(&cond_);
    }
    ~Condition_variable()
    {
        pthread_cond_destroy(&cond_);
    }
private:
    pthread_cond_t cond_;
};

Mutex.hpp (封装锁)

c++ 复制代码
#include <iostream>
#include <cstdlib>
#ifndef MUTEX_HPP
#define MUTEX_HPP
class Mutex
{
public:
    Mutex()
    {
        pthread_mutex_init(&mutex_, nullptr);
    }
    void lock()
    {
        pthread_mutex_lock(&mutex_);
    }
    void unlock()
    {
        pthread_mutex_unlock(&mutex_);
    }
    pthread_mutex_t* getMutex()
    {
        return &mutex_;
    }
    ~Mutex()
    {
        pthread_mutex_destroy(&mutex_);
    }
    Mutex(const Mutex& mtx) = delete;
    Mutex& operator=(const Mutex& mtx) = delete;
private:
    pthread_mutex_t mutex_;
};

class lock_Guard
{
public:
    lock_Guard(Mutex& mutex)
    :mutex_(mutex)
    {
        mutex_.lock();
    }
    ~lock_Guard()
    {
        mutex_.unlock();
    }
    pthread_mutex_t* getMutex()
    {
        return mutex_.getMutex();
    }
    lock_Guard(const lock_Guard& lg) = delete;
    lock_Guard& operator=(const lock_Guard& lg) = delete;
private:
    Mutex& mutex_;
};
#endif

main.cc

c++ 复制代码
#include "BlockQueue.hpp"
#include <pthread.h>
#define CUSTOMERSIZE 2
#define PRODUCTORSIZE 1
class Task
{
public:
    Task(int x,int y)
    :x_(x),y_(y)
    {}
    int operator()()
    {
        return x_ + y_;
    }
    int x_;
    int y_;
};
struct MyThread
{
    BlockQueue<Task>* rg;
    string name;
};
void* customer(void* args)
{
    MyThread* mt = (MyThread*)args;
    BlockQueue<Task>* rg = mt->rg;
    string name = mt->name;
    sleep(5);
    while(true)
    {
        Task task = rg->pop();
        int ans = task();
        cout << name << ": " << task.x_ << " + " << task.y_ << " = " << ans << endl;
    }
    return nullptr;
}
void* productor(void* args)
{
    MyThread* mt = (MyThread*)args;
    BlockQueue<Task>* rg = mt->rg;
    string name = mt->name;
    while(true)
    {
        int x = rand()%100+1;
        usleep(100);
        int y = rand()%100+1;
        rg->push(Task(x,y));
        cout << name << ": " << x << " + " << y << " = ?"<<endl;
        sleep(1);
    }
    return nullptr;
}
int main()
{
    srand(time(NULL));
    BlockQueue<Task> rg(3);
    MyThread c_mt[CUSTOMERSIZE];
    MyThread p_mt[PRODUCTORSIZE];
    pthread_t c[CUSTOMERSIZE];
    pthread_t p[PRODUCTORSIZE];
    for(int i=0;i<CUSTOMERSIZE;++i)
    {
        c_mt[i].rg = &rg;
        string name = "customer ";
        name += to_string(i+1);
        c_mt[i].name=name;
        pthread_create(c+i,nullptr,customer,(void*)(c_mt+i));
    } 
    for(int i=0;i<PRODUCTORSIZE;++i)
    {
        p_mt[i].rg = &rg;
        string name = "productor ";
        name += to_string(i+1);
        p_mt[i].name=name;
        pthread_create(p+i,nullptr,productor,(void*)(p_mt+i));
    } 

    for(int i=0;i<CUSTOMERSIZE;++i)
    {
        pthread_join(c[i],nullptr);
    } 
    for(int i=0;i<PRODUCTORSIZE;++i)
    {
        pthread_join(p[i],nullptr);
    } 
    return 0;
}

makefile

makefile 复制代码
blockQueue:main.cc
	g++ -o $@ $^ -std=c++11 -l pthread
.PHONY:clean
clean:
	rm -f blockQueue
相关推荐
showmeyourcode0.o11 分钟前
QT常用控件(1)
开发语言·c++·qt
qq_2430507913 分钟前
rtpmixsound:实现音频混音攻击!全参数详细教程!Kali Linux教程!
linux·web安全·网络安全·黑客·渗透测试·voip·kali linux
小黄人软件26 分钟前
C++ Visual Studio 2017厂商给的源码没有.sln文件 易兆微芯片下载工具加开机动画下载。
开发语言·c++·visual studio
不爱说话郭德纲39 分钟前
你需要来自XXX的权限才能对此文件夹进行更改?看我三步暴删
linux·windows·操作系统
AI迅剑1 小时前
模块二:C++核心能力进阶(5篇)篇二:《多线程编程:C++线程池与原子操作实战》(14万字深度指南)
java·开发语言·c++
oioihoii1 小时前
C++中锁与原子操作的区别及取舍策略
java·开发语言·c++
VU-zFaith8702 小时前
C++概率论算法详解:理论基础与实践应用
c++·算法·概率论
Ronin-Lotus2 小时前
嵌入式硬件篇---龙芯2k1000串口
linux·网络·python·嵌入式硬件·龙芯·2k1000
TangKenny2 小时前
Linux Maven Install
linux·运维·maven
小葡萄20252 小时前
黑马程序员C++核心编程笔记--4 类和对象--多态
java·c++·笔记