无处不在的生产者与消费者模型

目录

什么是生产者与消费者模型

工厂:勤劳的生产者

超市:中间的缓冲仓库

普通居民:热情的消费者

剧情上演

第一幕:工厂的忙碌与超市的充实

第二幕:消费者的热情与超市的热闹

第三幕:供需的平衡与协调

生活中的启示

提炼:

线程池--代码中的运用

(一)线程池是什么

(二)为什么需要线程池

引入锁和条件变量

那么我们说了有三种关系,那么我们需要几把锁呢?几个条件变量呢?

一份基本的基于阻塞队列的生产者消费者模型代码


什么是生产者与消费者模型

工厂:勤劳的生产者

街角的工厂里,机器日夜运转,工人们忙碌不停。他们生产着各种各样的商品,比如面包、饮料、日用品等。工厂的任务就是不停地制造这些商品,保证供应充足。

超市:中间的缓冲仓库

工厂生产出来的商品并不会直接送到居民手中,而是先运到街对面的超市。超市就像一个巨大的仓库,暂时存放着这些商品。它调节着工厂的生产节奏和居民的消费速度,防止工厂生产的商品堆积如山,也避免居民想买东西时却无货可买。

普通居民:热情的消费者

街上的居民们每天都有各种各样的需求,需要购买超市里的商品来满足生活。他们有的是上班族,下班后匆匆赶来买晚餐的食材;有的是家庭主妇,精心挑选着孩子的零食和生活用品。

剧情上演

第一幕:工厂的忙碌与超市的充实

清晨,工厂里就开始了一天的忙碌。工人们将一批批新鲜出炉的面包、香甜的饮料和各种日用品打包装箱。然后,这些商品被运送到超市。超市的员工们迅速将货物上架,摆放整齐,准备迎接顾客的到来。

此时,工厂就像一个不知疲倦的生产者,源源不断地制造商品;超市则是一个缓冲区,暂时存储着这些商品,等待消费者前来购买。

第二幕:消费者的热情与超市的热闹

随着太阳升高,居民们纷纷走出家门,来到超市购物。他们推着购物车,在货架间穿梭,挑选着自己需要的商品。有的居民在面包区挑选新鲜的面包,有的在饮料区挑选自己喜欢的饮品,还有的在日用品区挑选洗发水、牙膏等。

超市里人来人往,热闹非凡。居民们就像热情的消费者,不断地从超市这个“缓冲区”中取走商品,满足自己的生活需求。

第三幕:供需的平衡与协调

然而,有时候也会出现一些小状况。比如,工厂生产速度过快,而居民消费速度较慢,导致超市的库存积压。这时,工厂可能会接到超市的通知,暂时减缓生产速度,等库存减少后再恢复正常生产。

又或者,居民们突然对某种商品需求大增,而工厂的生产速度跟不上,导致超市该商品缺货。这时,超市会紧急通知工厂加快生产,同时可能会采取一些限购措施,保证每个居民都能买到一些。

在这个过程中,工厂、超市和居民之间不断地进行着信息交流和协调,就像生产者与消费者模型中的同步机制,确保整个系统的稳定运行。

生活中的启示

这个“生活剧”其实就是生产者与消费者模型的一个生动演绎。工厂对应生产者,居民对应消费者,而超市则相当于两者之间的缓冲区。通过这个模型,我们可以更好地理解生活中的许多场景,比如工厂与商场的货物供应、餐厅厨房与顾客的餐食提供等。它帮助我们优化资源配置,提高效率,让我们的生活更加有序和便捷

提炼:

1.共享或者临界资源
2.我们要研究生产消费模型,就需要研究清楚多个生产,多个消费的同步互斥关系!!!

生产者和生产者:互斥
消费者和消费者:互斥
生产者和消费者:互斥&&同步关系
总结:
3 种关系
2.种角色 -- 生产者和消费者
1 个交易场所

线程池--代码中的运用

(一)线程池是什么

线程池是一组预先创建并可重复使用的线程集合。它就像超市里的一支“员工团队”,这些员工平时处于待命状态,当有任务(比如搬运货物、整理货架、帮助顾客等)时,主管(相当于程序中的任务分配者)就会指派空闲的员工去完成,而不是每次有任务都临时招聘新员工。

(二)为什么需要线程池

频繁地创建和销毁线程会消耗系统资源,就像每次有任务都临时招聘员工一样,招聘、培训、解雇的过程都需要时间和成本。而线程池可以复用已有的线程,提高效率,就像超市有一支稳定的员工团队,可以快速响应各种任务,无需每次都走招聘流程。

引入锁和条件变量

比如生产者工厂在往超市进货的时候,在货架上放了一个面包,这时候消费者把这个面包拿走了。这是可以的嘛?我们超市知不知道呢;

答案是不知道的,所以我们放面包和拿面包的时候不能同时运行,这个时候我们就需要锁了

那么在超市与消费者之间,当消费者想要一个面包的时候,超市这个时候没有,然后消费者回到了家里面,他又在想这个时候超市上面包没有,然后他又回到超市去看,结果超市还是没有上面包,然后消费者就会白白跑。这个时候我们就可以引入条件变量,由超市告诉消费者。有没有资源?

那么我们说了有三种关系,那么我们需要几把锁呢?几个条件变量呢?

生产者和生产者:互斥
消费者和消费者:互斥
生产者和消费者:互斥&&同步关系

答案是一把锁,俩个条件变量。

在消费者中,如果没有资源,消费者会阻塞在条件变量中,每有一个资源就会放出一个消费者,那么消费者之间只需要竞争自己的条件变量就可以了。

那么在生产者中也同理,生产者竞争自己的条件变量。

但是生产者和消费者看见的是同一份资源,就是一个临界资源,我们就要对这个临界资源上锁,让放出来的生产者和消费者去竞争这一把锁。

一份基本的基于阻塞队列的生产者消费者模型代码

Block_queue.hpp

#pragma once
#include <iostream>
#include<queue>
#include <unistd.h>
#include <pthread.h>
using namespace std;
 static int nnn = 1;

namespace xjh
{
    const int num = 10; 
    template<typename T>
    class block_queue
    {
        public:
        block_queue(int cap,pthread_cond_t* conp,pthread_cond_t* conc,pthread_mutex_t* mutex)
        :_cap(cap)
        ,_condP(conp)
        ,_condC(conc)
        ,_mutex(mutex)
        {
            pthread_cond_init(_condP, nullptr);
            pthread_cond_init(_condC, nullptr);
            pthread_mutex_init(_mutex, nullptr);
        }
        void Push()
        {
            //sleep(1);
            pthread_mutex_lock(_mutex);
            while(_q.size() == _cap)
            {
                pthread_cond_wait(_condP,_mutex);
                cout<<"生产者等待"<<endl;
            }
            _q.push(nnn);
            cout<<"生产完毕唤醒消费者 "<<nnn<<endl;
            nnn++;
            pthread_cond_signal(_condC);
            pthread_mutex_unlock(_mutex);
        }
        void Pop()
        {
            sleep(1);
            int tmp = 0;
            pthread_mutex_lock(_mutex);
            while(_q.size() == 0)
            {
                pthread_cond_wait(_condC,_mutex);
                cout<<"消费者等待"<<endl;
            }
            tmp = _q.front();
            _q.pop();
            cout<<"消费完毕唤醒生产者 "<<tmp<<endl;
            pthread_cond_signal(_condP);
            pthread_mutex_unlock(_mutex);
        }
        ~block_queue()
        {
        }
        private:
        queue<T> _q;
        int _cap;
        pthread_cond_t* _condP;
        pthread_cond_t* _condC;
        pthread_mutex_t* _mutex;
    };
}

main.cc

#pragma once
#include <iostream>
#include<queue>
#include <unistd.h>
#include <pthread.h>
using namespace std;
 static int nnn = 1;

namespace xjh
{
    const int num = 10; 
    template<typename T>
    class block_queue
    {
        public:
        block_queue(int cap,pthread_cond_t* conp,pthread_cond_t* conc,pthread_mutex_t* mutex)
        :_cap(cap)
        ,_condP(conp)
        ,_condC(conc)
        ,_mutex(mutex)
        {
            pthread_cond_init(_condP, nullptr);
            pthread_cond_init(_condC, nullptr);
            pthread_mutex_init(_mutex, nullptr);
        }
        void Push()
        {
            //sleep(1);
            pthread_mutex_lock(_mutex);
            while(_q.size() == _cap)
            {
                pthread_cond_wait(_condP,_mutex);
                cout<<"生产者等待"<<endl;
            }
            _q.push(nnn);
            cout<<"生产完毕唤醒消费者 "<<nnn<<endl;
            nnn++;
            pthread_cond_signal(_condC);
            pthread_mutex_unlock(_mutex);
        }
        void Pop()
        {
            sleep(1);
            int tmp = 0;
            pthread_mutex_lock(_mutex);
            while(_q.size() == 0)
            {
                pthread_cond_wait(_condC,_mutex);
                cout<<"消费者等待"<<endl;
            }
            tmp = _q.front();
            _q.pop();
            cout<<"消费完毕唤醒生产者 "<<tmp<<endl;
            pthread_cond_signal(_condP);
            pthread_mutex_unlock(_mutex);
        }
        ~block_queue()
        {
        }
        private:
        queue<T> _q;
        int _cap;
        pthread_cond_t* _condP;
        pthread_cond_t* _condC;
        pthread_mutex_t* _mutex;
    };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值