当前位置: 首页 > news >正文

安塞网站建设网上推广平台

安塞网站建设,网上推广平台,网站建设需要什么硬件,网站栏目下拉菜单目录 一、生产者消费者模型的概念 二、生产者消费者模型的特点 三、生产者消费者模型优点 四、基于BlockingQueue的生产者消费者模型 4.1 基本认识 4.2 模拟实现 一、生产者消费者模型的概念 生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题 生产者和…

目录

一、生产者消费者模型的概念

二、生产者消费者模型的特点

三、生产者消费者模型优点

四、基于BlockingQueue的生产者消费者模型

4.1 基本认识

4.2 模拟实现


一、生产者消费者模型的概念

生产者消费者模式就是通过一个容器来解决生产者和消费者的强耦合问题

生产者和消费者彼此之间不直接通讯,而通过容器来通讯,所以生产者生产完数据之后不用等待消费者处理,直接将生产的数据放到这个容器当中;消费者也不用找生产者索要数据,而是直接从这个容器中取数据。容器就类似于一个缓冲区,平衡了生产者和消费者的处理能力,这个容器完成了生产者和消费者之间的解耦

二、生产者消费者模型的特点

  • 三种关系: 生产者和生产者(互斥关系)、消费者和消费者(互斥关系)、生产者和消费者(互斥关系、同步关系)
  • 两种角色: 生产者和消费者(通常由进程或线程承担)
  • 一个交易场所: 通常指的是内存中的一段缓冲区(可以自己通过某种方式组织)

生产者和生产者、消费者和消费者、生产者和消费者,它们之间为什么会存在互斥关系?

介于生产者和消费者之间的容器可能会被多个执行流同时访问,因此需要将该临界资源用互斥锁保护起来。所以所有生产者和消费者都会竞争式的申请锁,因此生产者和生产者、消费者和消费者、生产者和消费者之间都存在互斥关系

生产者和消费者之间为什么会存在同步关系?

若一直让生产者生产,那么当生产者生产的数据装满容器后,生产者再生产数据就会生产失败。
反之,让消费者一直消费,那么当容器当中的数据被消费完后,消费者再进行消费就会消费失败。
虽然这样不会造成任何数据不一致的问题,但是这样会引起另一方的饥饿问题,是非常低效的。应该让生产者和消费者访问该容器时具有一定的顺序性,比如让生产者先生产,然后再让消费者进行消费。

注意: 互斥关系保证的是数据的正确性,而同步关系是为了让多线程之间协同起来

三、生产者消费者模型优点

  • 解耦
  • 支持并发,提高效率
  • 支持忙闲不均

若在主函数中调用某一函数,那么必须等该函数体执行完后才继续执行主函数的后续代码,因此函数调用本质上是一种紧耦合。对应到生产者消费者模型中,函数传参实际上就是生产者生产的过程,而执行函数体实际上就是消费者消费的过程,但生产者只负责生产数据,消费者只负责消费数据,在消费者消费期间生产者可以同时进行生产,因此生产者消费者模型本质是一种松耦合

四、基于BlockingQueue的生产者消费者模型

4.1 基本认识

在多线程编程中,阻塞队列(Blocking Queue)是一种常用于实现生产者消费者模型的数据结构

其与普通的队列的区别在于:

  • 当队列为空时,从队列获取元素的操作将会被阻塞,直到队列中放入了元素
  • 当队列满时,往队列里存放元素的操作会被阻塞,直到有元素从队列中取出

阻塞队列最经典的应用场景:管道

4.2 模拟实现

下面以单生产者、单消费者为例进行讲解与实现

#include <iostream>
#include <queue>
#include <pthread.h>template <class T>
class BlockQueue
{
public:BlockQueue(size_t capacity = 4) : _capacity(capacity){pthread_mutex_init(&_mutex,nullptr);pthread_cond_init(&_full,nullptr);pthread_cond_init(&_empty,nullptr);}~BlockQueue(){pthread_mutex_destroy(&_mutex);pthread_cond_destroy(&_full);pthread_cond_destroy(&_empty);}void push(const T& data){pthread_mutex_lock(&_mutex);while (IsFull()) {//不能进行生产,直到阻塞队列可以容纳新的数据pthread_cond_wait(&_full, &_mutex);}_queue.push(data);std::cout << "Producer: " << data << std::endl;pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_empty); //唤醒在empty条件变量下等待的消费者线程}void pop(T& data){pthread_mutex_lock(&_mutex);while (IsEmpty()) {//不能进行消费,直到阻塞队列有新的数据pthread_cond_wait(&_empty, &_mutex);}data = _queue.front();_queue.pop();std::cout << "Consumer: " << data << std::endl;pthread_mutex_unlock(&_mutex);pthread_cond_signal(&_full); //唤醒在full条件变量下等待的生产者线程}private:bool IsFull() { return _queue.size() == _capacity; }bool IsEmpty() { return _queue.empty(); }private:std::queue<T> _queue;size_t _capacity;pthread_mutex_t _mutex;pthread_cond_t _full;pthread_cond_t _empty;
};

判断是否满足生产消费条件时不能用if,而应该用while:

pthread_cond_wait函数有可能调用失败,调用失败后该执行流就会继续往后执行。为了避免出现上述情况,就要让线程被唤醒后再次进行判断,确认是否真的满足生产消费条件,因此这里必须要用while进行判断

生产者消费者步调一致

#include <unistd.h>
#include "BlockQueue.hpp"void* Producer(void* arg)
{BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //生产者不断进行生产sleep(1);int data = rand() % 100 + 1;bq->push(data);}
}
void* Consumer(void* arg)
{int data = 0;BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //消费者不断进行消费sleep(1);bq->pop(data);}
}int main() 
{pthread_t producer,consumer;BlockQueue<int>* bq = new BlockQueue<int>;pthread_create(&producer,nullptr,Producer,(void*)bq);pthread_create(&consumer,nullptr,Consumer,(void*)bq);pthread_join(producer,nullptr);pthread_join(consumer,nullptr);delete bq;return 0;
}

由于代码中生产者是每隔一秒生产一个数据,而消费者是每隔一秒消费一个数据,因此运行代码后我们可以看到生产者和消费者的执行步调是一致的 

生产者速度快,消费者速度慢

void* Producer(void* arg)
{BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //生产者不断进行生产int data = rand() % 100 + 1;bq->push(data);}
}
void* Consumer(void* arg)
{int data = 0;BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //消费者不断进行消费sleep(1);bq->pop(data);}
}

此时由于生产者生产的很快,运行代码后一瞬间生产者就将阻塞队列装满。此时生产者想要再进行生产就只能在full条件变量下进行等待,直到消费者消费完一个数据后,生产者才会被唤醒进而继续进行生产,生产者生产完一个数据后又会进行等待,因此后续生产者和消费者的步调又变成一致的了

生产者速度慢,消费者速度快

void* Producer(void* arg)
{BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //生产者不断进行生产sleep(1);int data = rand() % 100 + 1;bq->push(data);}
}
void* Consumer(void* arg)
{int data = 0;BlockQueue<int>* bq = (BlockQueue<int>*)arg;while (true) { //消费者不断进行消费bq->pop(data);}
}

虽然消费者消费的快,但开始时阻塞队列中是没有数据的,因此消费者只能在empty条件变量下等待,直到生产者生产完一个数据后,消费者才会被唤醒进而进行消费,消费者消费完这一个数据后又会进行等待,因此生产者和消费者的步调就是一致的

设置唤醒策略

可以设置一些策略。譬如,下面当阻塞队列当中存储的数据大于队列容量的一半时,再唤醒消费者线程进行消费;当阻塞队列当中存储的数据小于队列容器的一半时,再唤醒生产者线程进行生产

void push(const T &data)
{pthread_mutex_lock(&_mutex);while (IsFull()) { // 不能进行生产,直到阻塞队列可以容纳新的数据pthread_cond_wait(&_full, &_mutex);}_queue.push(data);std::cout << "Producer: " << data << std::endl;if (_queue.size() >= _capacity / 2) {pthread_cond_signal(&_empty); // 唤醒在empty条件变量下等待的消费者线程}pthread_mutex_unlock(&_mutex);
}
void pop(T &data)
{pthread_mutex_lock(&_mutex);while (IsEmpty()) { // 不能进行消费,直到阻塞队列有新的数据pthread_cond_wait(&_empty, &_mutex);}data = _queue.front();_queue.pop();std::cout << "Consumer: " << data << std::endl;if (_queue.size() <= _capacity / 2) {pthread_cond_signal(&_full); // 唤醒在full条件变量下等待的生产者线程}pthread_mutex_unlock(&_mutex);
}

仍然让生产者生产快,消费者消费慢。运行代码后生产者还是一瞬间将阻塞队列装满后进行等待,但此时不是消费者消费一个数据就唤醒生产者线程,而是当阻塞队列当中的数据小于等于队列容器的一半时,才会唤醒生产者线程进行生产

基于任务的生产者消费者模型

实际使用生产者消费者模型时可不是简单的让生产者生产一个数字让消费者进行打印而已,前面的代码只是为了理解生产者消费者模型而已。
编写BlockingQueue时当中存储的数据就进行了模板化,那么就可以让BlockingQueue当中存储其他类型的数据。

譬如编写一个Task类(其中包含需要执行的任务),BlockingQueue中就存储Task对象。此时生产者放入阻塞队列的数据就是Task对象,而消费者从阻塞队列拿到Task对象后,就可以用该对象调用Run成员函数进行数据处理。

总之,根据需要进行编写即可


文章转载自:
http://dinncoamtrak.knnc.cn
http://dinncovexedly.knnc.cn
http://dinncoendoangiitis.knnc.cn
http://dinncomethotrexate.knnc.cn
http://dinncoproviding.knnc.cn
http://dinncosordidly.knnc.cn
http://dinncoairplane.knnc.cn
http://dinncosibylic.knnc.cn
http://dinncoinfraspecific.knnc.cn
http://dinncoaleph.knnc.cn
http://dinncogimpy.knnc.cn
http://dinncopathometer.knnc.cn
http://dinncobrine.knnc.cn
http://dinnconeuston.knnc.cn
http://dinncoexpellent.knnc.cn
http://dinncoagronomist.knnc.cn
http://dinncoabyssal.knnc.cn
http://dinncoadulator.knnc.cn
http://dinncoeutrophicate.knnc.cn
http://dinncoprofitability.knnc.cn
http://dinncoslopy.knnc.cn
http://dinncoearpiece.knnc.cn
http://dinncochainreactor.knnc.cn
http://dinncohypersurface.knnc.cn
http://dinncoiblis.knnc.cn
http://dinncosuperadd.knnc.cn
http://dinncorabbanite.knnc.cn
http://dinncodisuse.knnc.cn
http://dinncojoyhouse.knnc.cn
http://dinncoshortall.knnc.cn
http://dinncosententiously.knnc.cn
http://dinnconotum.knnc.cn
http://dinncodeimos.knnc.cn
http://dinncoudag.knnc.cn
http://dinncoaccompaniment.knnc.cn
http://dinncoimari.knnc.cn
http://dinncocollectivise.knnc.cn
http://dinncosquiz.knnc.cn
http://dinncobrrr.knnc.cn
http://dinncophytography.knnc.cn
http://dinncotyrosinase.knnc.cn
http://dinncodripple.knnc.cn
http://dinncobreak.knnc.cn
http://dinncoenglishman.knnc.cn
http://dinncoabernethy.knnc.cn
http://dinncoplaceman.knnc.cn
http://dinncorockford.knnc.cn
http://dinncohypnopedia.knnc.cn
http://dinnconeurine.knnc.cn
http://dinncopruritus.knnc.cn
http://dinncoquass.knnc.cn
http://dinncobabbler.knnc.cn
http://dinncotallyho.knnc.cn
http://dinncodepopulate.knnc.cn
http://dinnconemophila.knnc.cn
http://dinncomaker.knnc.cn
http://dinncokeel.knnc.cn
http://dinncoaegisthus.knnc.cn
http://dinnconever.knnc.cn
http://dinncoosi.knnc.cn
http://dinncomagniloquent.knnc.cn
http://dinncorubasse.knnc.cn
http://dinncowoodbine.knnc.cn
http://dinncocamerawork.knnc.cn
http://dinncographospasm.knnc.cn
http://dinncomotorcyclist.knnc.cn
http://dinncoacidophil.knnc.cn
http://dinncorighto.knnc.cn
http://dinncoindisciplinable.knnc.cn
http://dinncocanonistic.knnc.cn
http://dinncogrowthman.knnc.cn
http://dinncowisteria.knnc.cn
http://dinncospiritually.knnc.cn
http://dinncoplanimeter.knnc.cn
http://dinncoretardation.knnc.cn
http://dinncogeomorphology.knnc.cn
http://dinncotrimestral.knnc.cn
http://dinncoservia.knnc.cn
http://dinncotinnery.knnc.cn
http://dinncoscythe.knnc.cn
http://dinncostr.knnc.cn
http://dinncomarsupial.knnc.cn
http://dinncolimbic.knnc.cn
http://dinncorightfulness.knnc.cn
http://dinncomozzarella.knnc.cn
http://dinncosphalerite.knnc.cn
http://dinncojeton.knnc.cn
http://dinncodeoxidize.knnc.cn
http://dinncogeyserite.knnc.cn
http://dinncoshowup.knnc.cn
http://dinnconotam.knnc.cn
http://dinncophotochromic.knnc.cn
http://dinncoloadability.knnc.cn
http://dinncopickled.knnc.cn
http://dinncomatte.knnc.cn
http://dinncogid.knnc.cn
http://dinncopsychoneurosis.knnc.cn
http://dinncoepicentral.knnc.cn
http://dinncosphagnum.knnc.cn
http://dinncohemiretina.knnc.cn
http://www.dinnco.com/news/152631.html

相关文章:

  • 做网站只用php不用html爱站网爱情电影网
  • 搜题网站怎么制作小说排行榜百度搜索风云榜
  • 广电如何做视频网站百度seo排名优化公司哪家好
  • wordpress安装是什么杭州seo工作室
  • 深圳华强北手表各品牌批发杭州关键词优化测试
  • wordpress添加支付教程郑州网站seo服务
  • 最缺工的一百个职业网站排名优化培训课程
  • 哪些网站做的不好用怎么做好推广和营销
  • html5高端网站建设新乡网站seo
  • 珠宝网站设计西安优化外
  • 免费响应式模板网站模板下载竞价推广公司
  • 深圳网站建设合同范本最吸引人的营销广告词
  • 河南网站推广怎么做网络广告文案
  • 北京网站建设公司兴田德润专业长尾关键词快速排名软件
  • 马鞍山政府网站建设自助网站建设平台
  • 做造价在哪个网站查价格十大接单推广app平台
  • 做衣服上哪些网站苏州百度代理公司
  • 公司网站建设找谁做跨境电商平台
  • 陕西网站建设哪家强软文推广渠道
  • 自己做视频会员网站重庆seo网站排名
  • 做网站给菠菜引流百度竞价点击价格公式
  • 移动网站做微信小程序seo优化的优点
  • 做网站接广告放单平台
  • 徐州建设工程审图中心网站青岛百度推广优化怎么做的
  • 织梦网站导航浮动网络广告销售
  • 贵州网站制作设计公司提供seo顾问服务适合的对象是
  • 做的比较好的公司网站自助建站系统哪个好用
  • nike网站建设分析千峰培训出来好就业吗
  • 仿今日头条网站模板广东深圳龙华区
  • 小程序商城图片首页排名优化公司