构建基于 阻塞队列 / 环形队列 的高效生产消费者模型系统

1. 生产者-消费者问题 概述

生产-消费者模型 :一个或多个 生产者线程 产生数据并将其放入共享缓冲区,同时一个或多个 消费者线程 从该缓冲区中读取数据进行操作的情景。

缓冲区 是一个用于存储生产者产生数据的中间容器;缓冲区 的容量通常是有限的,只能容纳一定数量的数据项。

生产 - 消费者模型的核心问题: 1. 线程与线程之间的 同步互斥 关系;生产者与消费者之间的 等待唤醒 机制。

2. 阻塞队列

在这里插入图片描述

2.1 工作原理
  • 队列为空时,消费者从队列中消费数据时,会被阻塞挂起,直至队列中有元素可用;

  • 队列为满时,生产者向队列中生产数据时,会被阻塞挂起,直至队列中有空闲位置;

  • 使用 条件变量(pthread_cond_t 类型)+ 锁(pthread_mutex_t 类型)实现 等待 和 唤醒 机制。

2.2 框架
#include <iostream>
#include <queue>
#include <pthread.h>

template<class T>
class BlockQueue
{
   
public:
	BlockQueue(int cap) :_cap(cap), _producer_wait_num(0), _consumer_wait_num(0)
    {
   
        pthread_mutex_init(&_mutex, nullptr);
        
        pthread_cond_init(&_producer_cond, nullptr);
        pthread_cond_init(&_consumer_cond, nullptr);
    }
    
	~BlockQueue() 
    {
   
        pthread_mutex_destroy(&_mutex);
        
        pthread_cond_destroy(&_producer_cond);
        pthread_cond_destroy(&_consumer_cond);
    }    
private:
    queue<T> _block_queue; // 生产者生产任务,消费者处理任务
	int _cap; // 容量
    
    pthread_mutex_t _mutex; // 保护共享资源的互斥锁
    
    pthread_cond_t _producer_cond; // 用于唤醒生产者生产
    pthread_cond_t _consumer_cond; // 用于唤醒消费者消费
    
    int _producer_wait_num; // 记录阻塞挂起的生产者数量
    int _consumer_wait_num; // 记录阻塞挂起的消费者数量
};

pthread_mutex_t _mutex; // 保护共享资源的互斥锁

解释 “为什么消费者和生产者共用一把锁” :

  1. 阻塞队列是一个共享资源,生产者和消费者都需要访问同一段内存资源来插入和删除元素;为了防止数据竞争和不一致,必须保证同一时间只有一个线程可以访问队列

  2. 使用单个锁可以确保生产者和消费者访问队列时不会发生冲突。

2.3 生产消费
  • 生产
template<class T>
class BlockQueue
{
   
public:
    void Enqueue(T& in)
    {
   
        phtread_mutex_lock(&_mutex); // 加锁
        while (_block_queue.size() == _cap) // 阻塞队列为满
        {
   
            ++_producer_wait_num;
            pthread_cond_signal(&_consumer_cond); // 唤醒消费者线程
            pthread_cond_wait(&_producer_cond, &_mutex); // 阻塞挂起, 释放锁
            --_producer_wait_num;
        }
        
        _block_queue.push(in);
        if (_consumer_wait_num > 0) // 唤醒 阻塞挂起的消费者线程
            pthread_cond_signal(&_consumer_cond); 
        pthread_mutex_unlock
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值