生产者消费者问题

Celery详解(1)

妖精的绣舞 提交于 2019-12-19 12:51:20
在学习Celery之前,我先简单的去了解了一下什么是生产者消费者模式。 生产者消费者模式 在实际的软件开发过程中,经常会碰到如下场景:某个模块负责产生数据,这些数据由另一个模块来负责处理(此处的模块是广义的,可以是类、函数、线程、进程等)。产生数据的模块,就形象地称为生产者;而处理数据的模块,就称为消费者。 单单抽象出生产者和消费者,还够不上是生产者消费者模式。该模式还需要有一个缓冲区处于生产者和消费者之间,作为一个中介。生产者把数据放入缓冲区,而消费者从缓冲区取出数据,如下图所示: 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过消息队列(缓冲区)来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给消息队列,消费者不找生产者要数据,而是直接从消息队列里取,消息队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。这个消息队列就是用来给生产者和消费者解耦的。------------->这里又有一个问题,什么叫做解耦? 解耦 :假设生产者和消费者分别是两个类。如果让生产者直接调用消费者的某个方法,那么生产者对于消费者就会产生依赖(也就是耦合)。将来如果消费者的代码发生变化,可能会影响到生产者。而如果两者都依赖于某个缓冲区,两者之间不直接依赖,耦合也就相应降低了。生产者直接调用消费者的某个方法,还有另一个弊端

人生苦短之我用Python篇(队列、生产者和消费者模型)

社会主义新天地 提交于 2019-12-18 01:37:31
队列: queue. Queue ( maxsize=0 ) #先入先出 queue. LifoQueue ( maxsize=0 ) #last in fisrt out queue. PriorityQueue ( maxsize=0 ) #存储数据时可设置优先级的队列 Queue. qsize ( ) Queue. put ( item , block=True , timeout=None ) Queue. put_nowait ( item ) Queue. get ( block=True , timeout=None ) Queue. get_nowait ( ) Queue. empty ( ) #return True if empty Queue. full ( ) # return True if full import queue q = queue.PriorityQueue() q.put((-1,"chenronghua")) q.put((3,"hanyang")) q.put((10,"alex")) q.put((6,"wangsen")) print(q.get()) print(q.get()) print(q.get()) print(q.get()) q = queue.LifoQueue() q.put(1) q.put(2) q

day 7-5 生产者消费者模型

时间秒杀一切 提交于 2019-12-18 00:07:22
一. 生产者和消费者模型 在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产线程和消费线程的工作能力来提高程序的整体处理数据的速度。 二. 为什么要使用生产者和消费者模式 在线程世界里,生产者就是生产数据的线程,消费者就是消费数据的线程。在多线程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。 三. 什么是生产者消费者模式 生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。 四. 基于队列实现生产者消费者模型 1 from multiprocessing import Queue,Process 2 import time 3 4 def pro(p): 5 for i in range(3): 6 res = "包子%s" %i 7 time.sleep(2) 8 print("生产者生产了: %s" %res) 9 p.put(res)

条件变量与生产者消费者问题

佐手、 提交于 2019-12-17 08:57:23
文章目录 使用 if而非 while且只有一个条件变量 使用while但只有一个条件变量 使用while且有两个条件变量 扩展缓冲区大小(从1到数组) 本文主要是探讨<<操作系统导论>>一书第30章-条件变量的知识. 书中介绍了条件变量的概念, 并将条件变量运用在生产者消费者问题中. 从最简单的情况开始, 列举了使用条件变量解决生产者消费者问题的几种错误用法. 本文主要是对这几种情况的代码模拟分析, 分为以下四个部分 使用 if而非 while且只有一个条件变量 使用while但只有一个条件变量 使用while且有两个条件变量 扩展缓冲区大小(从1到数组) 使用 if而非 while且只有一个条件变量 书中提供的第一个方案(有问题), 给生产者和消费者共用一个条件变量, 且使用if来判断缓存区 问题: wait的条件使用了if而不是while, 导致如果有多个消费者的情况, 当一个阻塞的消费者被生产者唤醒了, 准备执行但这时另一个消费者抢占执行并进行了消费导致缓冲区空了. 这时切换到第一个消费者消费, 因为缓冲区空了触发断言, 程序错误. 如果换成while, 那么第二个消费者在醒来的时候, 就会再判断一下条件是否成立, 由于被另一个消费者消费了, 所以它又会调用wait被阻塞. 需要注意wait函数的执行过程. 当一个线程执行wait的时候, 会释放它持有的锁,

rabbitmq常见面试题

橙三吉。 提交于 2019-12-13 02:21:55
1、使用RabbitMQ有什么好处? 1.解耦,系统A在代码中直接调用系统B和系统C的代码,如果将来D系统接入,系统A还需要修改代码,过于麻烦! 2.异步,将消息写入消息队列,非必要的业务逻辑以异步的方式运行,加快响应速度 3.削峰,并发量大的时候,所有的请求直接怼到数据库,造成数据库连接异常 2、RabbitMQ 中的 broker 是指什么?cluster 又是指什么? broker 是指一个或多个 erlang node 的逻辑分组,且 node 上运行着 RabbitMQ 应用程序。cluster 是在 broker 的基础之上,增加了 node 之间共享元数据的约束。 3、RabbitMQ 概念里的 channel、exchange 和 queue 是逻辑概念,还是对应着进程实体?分别起什么作用? queue 具有自己的 erlang 进程;exchange 内部实现为保存 binding 关系的查找表;channel 是实际进行路由工作的实体,即负责按照 routing_key 将 message 投递给 queue 。由 AMQP 协议描述可知,channel 是真实 TCP 连接之上的虚拟连接,所有 AMQP 命令都是通过 channel 发送的,且每一个 channel 有唯一的 ID。一个 channel 只能被单独一个操作系统线程使用,故投递到特定

系统学习消息队列分享(四) 消息模型:主题和队列有什么区别?

烂漫一生 提交于 2019-12-12 16:57:19
这节课我们来学习消息队列中像队列、主题、分区等基础概念。这些基础的概念,就像我们学习一门编程语言中的基础语法一样,你只有搞清楚它们,才能进行后续的学习。 如果你研究过超过一种消息队列产品,你可能已经发现,每种消息队列都有自己的一套消息模型,像队列(Queue)、主题(Topic)或是分区(Partition)这些名词概念,在每个消息队列模型中都会涉及一些,含义还不太一样。 为什么出现这种情况呢?因为没有标准。曾经,也是有一些国际组织尝试制定过消息相关的标准,比如早期的 JMS 和 AMQP。但让人无奈的是,标准的进化跟不上消息队列的演进速度,这些标准实际上已经被废弃了。 那么,到底什么是队列?什么是主题?主题和队列又有什么区别呢?想要彻底理解这些,我们需要从消息队列的演进说起。 主题和队列有什么区别? 在互联网的架构师圈儿中间,流传着这样一句不知道出处的名言,我非常认同和喜欢:好的架构不是设计出来的,而是演进出来的。 现代的消息队列呈现出的模式,一样是经过之前的十几年逐步演进而来的。 最初的消息队列,就是一个严格意义上的队列。在计算机领域,“队列(Queue)”是一种数据结构,有完整而严格的定义。在维基百科中,队列的定义是这样的: 队列是先进先出(FIFO, First-In-First-Out)的线性表(Linear List)。在具体应用中通常用链表或者数组来实现

生产者-消费者设计模式

▼魔方 西西 提交于 2019-12-10 03:02:59
一、生产者消费者设计模式 1、中间队列 一段内存空间,且可存取; 2、两种角色 (1)生产者:生产数据; (2)消费者:消费数据。 3、三种关系 (1)生产者与生产者的互斥关系; (2)消费者与消费者的互斥关系; (3)生产者与消费者的互斥且同步关系。 二、实现方式 1、使用synchronized(wait()和notify()) 2、使用Lock实现(await()和signal()) 3、阻塞队列实现 三、生产者-消费者模型的优点 1、解耦:降低生产者和消费之间的依赖关系 2、支持并发 即生产者和消费者是两个可以独立的并发主体,互不干扰的运行,如果没有中间的环节,则会生产者阻塞或者消费者阻塞。不管是哪种方法效率都比较低。 3、支持盲闲不均 如果生产数据的速度时快时慢,缓冲区可以对其进行适当缓冲。当生产的数据太块时,消费者来不及处理,未处理的数据可以暂时存在缓冲区。等生产者的生产速度慢下来,消费者再慢慢处理掉。 四、提升与思考 1、队列可以有多种实现: (1)先放先出:FIFO (2)后放先出:LIFO (3)优先级队列:Priority Queue 2、为什么生产和消费要用多线程 单线程太耗时,只有当多线程的效率提升可以抵消开发难度和性能消耗时才有必要用多线程; 3、别忘记sychronized和notifyAll() 否则其他线程一直等待,不会继续 4

进程间通信(IPC机制)

扶醉桌前 提交于 2019-12-08 19:31:34
目录 进程间通信(IPC机制) 队列 生产者消费者 进程间通信(IPC机制) 问题 :虽然可以用文件共享数据显示进程间数据通信但问题是 效率低(共享数据基于文件,而文件是硬盘上的数据) 需要自己加锁处理 针对上述问题,我们需要找到一种更加合理快捷的方式,那就是队列和管道 这两种方式都是可以实现进程间数据传输的,由于队列是管道+锁的方式实现,所以我们着重研究队列即可 队列 创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。 大白话就是队列支持多个人从队列的一段放入数据,同样支持多个人从队列的另一端取数据 用法 Queue([maxsize]) # 创建共享的进程队列,队列底层使用管道和锁定实现 # 参数:maxsize是队列中允许的最大项数。如果省略次参数,则无大小限制 代码实现 from multiprocessing import Queue q = Queue(3) # 创建一个最大只能容纳3个数据的队列 """ 常用方法:put、get、put_nowait、get_nowait、full、empty """ q.put('sean') q.put('tank') q.put('jason') q.put('111') # 只要队列满了,会进入阻塞 try: q.put_nowait(3) # 可以使用put_nowait

RabbitMQ基础知识详解

送分小仙女□ 提交于 2019-12-06 22:51:02
什么是MQ? MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法。MQ是消费-生产者模型的一个典型的代表,一端往消息队列中不断写入消息,而另一端则可以读取队列中的消息。 RabbitMQ是MQ的一种。下面详细介绍一下RabbitMQ的基本概念。 1、队列、生产者、消费者 队列是RabbitMQ的内部对象,用于存储消息。生产者(下图中的P)生产消息并投递到队列中,消费者(下图中的C)可以从队列中获取消息并消费。 多个消费者可以订阅同一个队列,这时队列中的消息会被平均分摊给多个消费者进行处理,而不是每个消费者都收到所有的消息并处理。 2、Exchange、Binding 刚才我们看到生产者将消息投递到队列中,实际上这在RabbitMQ中这种事情永远都不会发生。实际的情况是,生产者将消息发送到Exchange(交换器,下图中的X),再通过Binding将Exchange与Queue关联起来。 3、Exchange Type、Bingding key、routing key 在绑定(Binding)Exchange与Queue的同时,一般会指定一个binding key。在绑定多个Queue到同一个Exchange的时候,这些Binding允许使用相同的binding key。 生产者在将消息发送给Exchange的时候,一般会指定一个routing

全网最通俗易懂的Kafka入门!

守給你的承諾、 提交于 2019-12-06 16:22:13
摘自: https://www.cnblogs.com/Java3y/p/11982381.html 全网最通俗易懂的Kafka入门! 前言 只有光头才能变强。 文本已收录至我的GitHub仓库,欢迎Star: https://github.com/ZhongFuCheng3y/3y 在这篇之前已经写过两篇基础文章了, 强烈建议 先去阅读: 什么是ZooKeeper? 什么是消息队列? 众所周知,消息队列的产品有好几种,这里我选择学习Kafka的原因,无他,公司在用。 我司使用的是Kafka和自研的消息队列(Kafka和RocketMQ)改版,于是我就想学学Kafka这款消息队列啦。本篇文章对Kafka入门,希望对大家有所帮助。 本文知识点提前预览: 这篇文章花了我很长时间画图,目的是希望以最通俗易懂的方式带大家入门,如果觉得不错, 希望能给我点个赞 ! 一、什么是Kafka? 首先我们得去官网看看是怎么介绍Kafka的: https://kafka.apache.org/intro 在收集资料学习的时候,已经发现有不少的前辈对官网的介绍进行翻译和总结了,所以我这里就不重复了,贴下地址大家自行去学习啦: https://scala.cool/2018/03/learning-kafka-1/ https://colobu.com/2014/08/06/kafka