【Linux】线程——生产者消费者模型、基于阻塞队列的生产消费者模型、基于环形队列的生产消费者模型、POSIX信号量的概念和使用

Linux线程

6. 生产消费者模型

生产消费者模型的概念

  生产者消费者模型 是一种常见的并发编程模型。

  在这个模型中,通常存在两类角色:生产者和消费者。

  生产者负责生成数据或产品,并将其放入一个共享的缓冲区中。而消费者则从缓冲区中取出数据或产品进行消费处理。

  

为何要使用生产者消费者模型

  生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个阻塞队列就是用来给生产者和消费者解耦的。

  

  简单的说:就是为了解决生产者和消费者之间的速度不匹配问题。

  

生产者消费者模型优点

  解耦、支持并发、支持忙闲不均。

在这里插入图片描述
  

  上图中有"321"原则:

  3种关系:生产者和生产者(互斥)、消费者和消费者(互斥)、生产者和消费者(互斥、同步)。

  2种角色:生产者和消费者。

  1个交易场所:特定结构的内存空间。

  

6.1 基于阻塞队列的生产消费者模型

基于阻塞队列的生产消费者模型的概念

  基于阻塞队列的生产消费者模型 是一种用于协调生产者和消费者之间工作流程的编程模式。

  

实现的原理

  在这个模型中,生产者负责生成数据或产品,并将其放入一个阻塞队列中。阻塞队列是一种特殊的数据结构,当队列已满时,生产者尝试添加新元素的操作会被阻塞,直到队列有足够的空间。

  消费者则从这个阻塞队列中获取数据或产品进行处理。当队列为空时,消费者尝试获取元素的操作会被阻塞,直到生产者向队列中添加了新的元素。

  

在这里插入图片描述

  

6.1.1 阻塞队列模型实现

  这是我们的任务对象,一个简单的模拟加减乘除计算:

#pragma once
#include <iostream>
#include <string>

std::string opers="+-*/%";

enum{
   
    DivZero=1,
    ModZero,
    Unknown
};

class Task
{
   
public:
    Task()
    {
   }
    
    Task(int x,int y,char op)
        :_data1(x),_data2(y),_oper(op),_result(0),_exitcode(0)
    {
   }

    void run()
    {
   
        switch (_oper)
        {
   
        case '+':
            _result=_data1+_data2;
            break;
        case '-':
            _result=_data1-_data2;
            break;
        case '*':
            _result=_data1*_data2;
            break;
        case '/':
            {
   
                if(_data2==0) _exitcode=DivZero;
                else _result=_data1/_data2;
            }
            break;
        case '%':
            {
   
                if(_data2==0) _exitcode=ModZero;
                else _result=_data1%_data2;
            }
            break;
        default:
            _exitcode=Unknown;
            break;
        }
    }

    //Task对象重载运算符(),()直接进行run函数
    void operator()()
    {
   
        run();
    }

    std::string GetResult()
    {
   
        std::string r=std::to_string(_data1);
        r+=_oper;
        r+=std::to_string(_data2);
        r+="=";
        r+=std::to_string(_result);
        r+="[code: ";
        r+=std::to_string(_exitcode);
        r+="]";

        return r;
    }

    std::string GetTask()
    {
   
        std::string r=std::to_string(_data1);
        r+=_oper;
        r+=std::to_string(_data2);
        r+="=?";
        return r;
    }

    ~Task()
    {
   }

private: 
    int _data1;
    int _data2;
    char _oper;

    int _result;
    int _exitcode;
};

  

  这是我们实现的阻塞队列模型:

#pragma once

#include <iostream>
#include <queue>
#include 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鳄鱼麻薯球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值