生产消费模型

目录

1 模型简介

2 基于BlockingQueue的生产者消费者模型

代码实现

3 基于环形队列的生产消费模型

 代码实现


1 模型简介

        以现实中的生产消费为例。工厂作为生产者生产的产品被批发到商场,普通民众作为消费者到商场购买产品。在这之间生产者与消费者并不需要交互,而是通过商场这一个媒介完成整个生产消费的过程。

        那么在我们的程序中也可以应用这个模型,一个线程产生数据作为生产者,一个线程处理数据作为消费者,中间使用阻塞队列来作为缓冲区。这样做的好处就是将生产和消费的行为分离,消费者不需要重复等待着生产者生产。提高了线程执行的效率。


2 基于BlockingQueue的生产者消费者模型

        使用队列作为缓冲区的数据结构。在队列为空时,我们认为当前没有产品被生产,无法进行消费需要等待生产者生产;在队列为满时,我们认为。当前仓库已满,生产者不能再生产了,需要等待消费者消费。

代码实现

#pragma once

#include <iostream>
#include <queue>
#include <pthread.h>

namespace ns_blockqueue
{
    const int default_cap = 5;

    template<class T>
    class BlockQueue
    {
    public:
        BlockQueue(int cap = default_cap):_cap(cap)
        {
            pthread_mutex_init(&_mtx,nullptr);
            pthread_cond_init(&_isfull,nullptr);
            pthread_cond_init(&_isempty,nullptr);
        }
        ~BlockQueue()
        {
            pthread_mutex_destroy(&_mtx);
            pthread_cond_destroy(&_isfull);
            pthread_cond_destroy(&_isempty);
        }
        void push(const T &in)
        {
            LockQueue();
            while(isFull())//循环检测确保一定是因为不满足条件跳出循环
            {
                ProductWait();
            }
            _bq.push(in);
            WakeupConsumer();
            UnlockQueue();
        }
        void pop(T *out)
        {
            LockQueue();
            while(isEmpty())
            {
                ConsumerWait();
            }
            *out = _bq.front();
            _bq.pop();
            WakeupProducter();
            UnlockQueue();
        }
    private:
        bool isFull()
        {
            return _bq.size() == _cap;
        }
        bool isEmpty()
        {
            return _bq.size() == 0;
        }
        void LockQueue()
        {
            pthread_mutex_lock(&_mtx);
        }
        void UnlockQueue()
        {
            pthread_mutex_unlock(&_mtx);
        }
        void ProductWait()
        {
            pthread_cond_wait(&_isempty,&_mtx);
        }
        void ConsumerWait()
        {
            pthread_cond_wait(&_isfull,&_mtx);
        }
        void WakeupProducter()
        {
            pthread_cond_signal(&_isempty);
        }
        void WakeupConsumer()
        {
            pthread_cond_signal(&_isfull);
        }
    private:
        std::queue<T> _bq;
        int _cap;
        pthread_mutex_t _mtx;
        pthread_cond_t _isfull;
        pthread_cond_t _isempty;

    };
} 

3 基于环形队列的生产消费模型

        将中间的仓库使用环形队列的结构。环形队列通过数组模拟,通过取余运算达到环形,同时利用信号量计数来对队列进行判空或判满。

 代码实现

#pragma once

#include <iostream>
#include <vector>
#include <semaphore.h>
#include <pthread.h>

namespace ns_ring_queue
{
    const int g_cap_default =10;
    template<class T>
    class RingQueue
    {
    public:
        RingQueue(int cap = g_cap_default)
            :_ring_queue(cap),_cap(cap),_c_step(0),_p_step(0)
        {
            sem_init(&_blank_sem,0,cap);
            sem_init(&_data_sem,0,0);

            pthread_mutex_init(&_c_mtx,nullptr);
            pthread_mutex_init(&_p_mtx,nullptr);
        }
        ~RingQueue()
        {
            sem_destroy(&_blank_sem);
            sem_destroy(&_data_sem);

            pthread_mutex_destroy(&_c_mtx);
            pthread_mutex_destroy(&_p_mtx);
        }
        void pop(T* out)
        {
            sem_wait(&_data_sem);

            pthread_mutex_lock(&_c_mtx);
            *out = _ring_queue[_c_step];
            _c_step++;
            _c_step %= _cap;
            pthread_mutex_unlock(&_c_mtx);

            sem_post(&_blank_sem);

        }
        void push(const T& in)//==生产
        {
            sem_wait(&_blank_sem);

            pthread_mutex_lock(&_p_mtx);
            _ring_queue[_p_step] = in;
            _p_step++;
            _p_step %= _cap;
            pthread_mutex_unlock(&_p_mtx);

            sem_post(&_data_sem);

        }
    private:
        std::vector<T> _ring_queue;
        int _cap;
        sem_t _blank_sem;
        sem_t _data_sem;
        int _c_step;
        int _p_step;
        pthread_mutex_t _c_mtx;
        pthread_mutex_t _p_mtx;
    };
    
} // namespace ns_ring_queue

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值