生产者消费者模型当中有两大类重要的角色,一个是生产者(负责造数据的任务),另一个是消费者(接收造出来的数据进行进一步的操作)。

为什么要使用生产者消费者模型?

在并发编程中,如果生产者处理速度很快,而消费者处理速度比较慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个等待的问题,就引入了生产者与消费者模型。让它们之间可以不停的生产和消费。

实现生产者消费者模型三要素:

1、生产者

    2、消费者

    3、队列(或其他的容哭器,但队列不用考虑锁的问题)

什么时候用这个模型?

程序中出现明显的两类任务,一类任务是负责生产,另外一类任务是负责处理生产的数据的(如爬虫)

用该模型的好处?

1、实现了生产者与消费者的解耦和

2、平衡了生产力与消费力,就是生产者一直不停的生产,消费者可以不停的消费,因为二者不再是直接沟通的,而是跟队列沟通的。

来简单的写一个生产者消费者模型:

import time
import random
from multiprocessing import Queue,Processdef consumer(name,q):while True:res=q.get()time.sleep(random.randint(1,3))print('消费者》》%s 准备开吃%s。'%(name,res))def producer(name,q):for i in range(5):time.sleep(random.randint(1,2))res='大虾%s'%iq.put(res)print('生产者》》》%s 生产了%s'%(name,res))if __name__ == '__main__':q=Queue()#一个队列p1=Process(target=producer,args=('monicx',q))c1=Process(target=consumer,args=('lili',q))p1.start()c1.start()

运行效果:

现在确实让生产者不停的生产,消费者不断的消费。,但此时有一个问题就是主进程没有结束。原因是:生产者p1生产完后就结束了,但是消费者c1,在q.get()取空之后,就一直在原地等待。解决这个问题无非就让生产者在生产完毕后,就再往队列中发送一个结束信号,这样消费者接收到结束信号后就可以跳出死循环。

import time
import random
from multiprocessing import Queue,Processdef consumer(name,q):
    while True:
        res=q.get()if res is None:break
        time.sleep(random.randint(1,3))print('消费者》》%s 准备开吃%s。'%(name,res))def producer(name,q):
    for i in range(5):
        time.sleep(random.randint(1,2))
        res='大虾%s'%iq.put(res)print('生产者》》》%s 生产了%s'%(name,res))if __name__ == '__main__':
    q=Queue()#一个队列

    p1=Process(target=producer,args=('monicx',q))c1=Process(target=consumer,args=('lili',q))p1.start()c1.start()p1.join()q.put(None)

运行结果:

虽然解决了问题,但是这种的解决方式,在有多个生产者和多个消费者时,有几个消费者就要发送几次的结束信号,不然程序就不会停止。相当的low。就像这样:

import time
import random
from multiprocessing import Queue,Processdef consumer(name,q):
    while True:
        res=q.get()if res is None:break
        time.sleep(random.randint(1,3))print('消费者》》%s 准备开吃%s。'%(name,res))def producer(name,q):
    for i in range(5):
        time.sleep(random.randint(1,2))
        res='大虾%s'%iq.put(res)print('生产者》》》%s 生产了%s'%(name,res))if __name__ == '__main__':
    q=Queue()#实例一个队列

    p1=Process(target=producer,args=('monicx1',q))p2=Process(target=producer,args=('monicx2',q))c1=Process(target=consumer,args=('lili1',q))c2=Process(target=consumer,args=('lili2',q))c3=Process(target=consumer,args=('lili3',q))p1.start()p2.start()c1.start()c2.start()c3.start()p1.join()p2.join()q.put(None)q.put(None)q.put(None)

我们的思路就是发送结束信号而已,有另外一种队列提供了这种机制。

JoinableQueue([maxsize])

这就像是一个Queue对象,但队列允许项目的使用者通知生产者项目已经被处理。通知进程是使用共享的信号和条件变量来实现的。

其中maxsize是队列中允许最大项数,省略则无大小限制。

JoinableQueue的实例q除了与Queue对象相同的方法之外还具有:

task_done():消费者用此方法发出信息,表示q.get()的返回项目已经被处理。如果调用此方法的次数大于从队列中删除项目的数量,将会导致ValueError异常。

join():生产者调用此方法进行阻塞,直到队列中所有的项目都被处理了。

import time
import random
from multiprocessing import Process
from multiprocessing import JoinableQueuedef consumer(name,q):while True:res=q.get()time.sleep(random.randint(1,3))print('\033[43m消费者》》%s 准备开吃%s\033[0m'%(name,res))q.task_done()#发送信号给生产者的q.join()说,已经处理完从队列中拿走的一个项目def producer(name,q):for i in range(5):time.sleep(random.randint(1,2))#模拟生产时间res='大虾%s'%iq.put(res)print('\033[40m生产者》》》%s 生产了%s\033[0m'%(name,res))q.join()#等到消费者把自己放入队列中的所有项目都取走处理完后调用task_done()之后,生产者才能结束if __name__ == '__main__':q=JoinableQueue()#实例一个队列p1=Process(target=producer,args=('monicx1',q))p2=Process(target=producer,args=('monicx2',q))c1=Process(target=consumer,args=('lili1',q))c2=Process(target=consumer,args=('lili2',q))c3=Process(target=consumer,args=('lili3',q))c1.daemon=Truec2.daemon=Truec3.daemon=Truep1.start()p2.start()c1.start()c2.start()c3.start()p1.join()p2.join() 

运行结果:

(python)生产者消费者模型相关推荐

  1. Python 生产者消费者模型

    Python 生产者消费者模型 文章目录 Python 生产者消费者模型 生产者消费者模型介绍 生产者消费者模型实现 函数yield 方式 多进程方式 实现一. 实现二. 多线程方式 生产者消费者模型 ...

  2. python—生产者消费者模型

    python-生产者消费者模型 生产者和消费者模式是多线程开发中经常见到的一种模式.生产者的线程专门用来生产一些数据,然后存放到一个中间的变量中.消费者再从这个中间的变量中取出数据进行消费.通过生产者 ...

  3. python 生产者-消费者模型 - 代码示例

    代码示例 #!/usr/bin/env python #encoding: utf-8 import threading import timecondition = threading.Condit ...

  4. Python之路(第三十八篇) 并发编程:进程同步锁/互斥锁、信号量、事件、队列、生产者消费者模型...

    一.进程锁(同步锁/互斥锁) 进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的, 而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理. 例 ...

  5. python多线程实现生产者消费者_用Python实现多线程“生产者-消费者”模型的简单例子...

    用 Python 实现多线程"生产者 - 消费者"模型的简单例子 生产者消费者问题是一个著名的线程同步问题, 该问题描述如下: 有一个生产者在生产产品, 这些产品将提供给若干个消费 ...

  6. python生产教程_python入门教程12-09 (python语法入门之生产者消费者模型)

    Python中的生产者消费者模型,在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题,是本章的重点内容,下面我们一起来看看吧. 生产者消费者模型 在并发编程中使用生产者和消费者模式能够解决绝大 ...

  7. Python并行编程(四):多线程同步之condition(条件变量)实现带有缓冲区的生产者-消费者模型...

    什么是Condtion? 所谓condition条件变量,即这种机制是在满足了特定的条件后,线程才可以访问相关的数据. 这种同步机制就是一个线程等待特定的条件,另一个线程通知它条件已经发生.一旦条件发 ...

  8. python之生产者消费者模型

    python之生产者消费者模型 生产者消费者模型作用于: 1.爬虫的时候 2.分布式操作:celery 其本质:就是让生产数据和消费数据的效率达到平衡并且最大化的效率 为什么要使用生产者消费者模型? ...

  9. python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))...

    昨日内容回顾 python中启动子进程 并发编程 并发 :多段程序看起来是同时运行的 ftp 网盘 不支持并发 socketserver 多进程 并发 异步 两个进程 分别做不同的事情 创建新进程 j ...

  10. Python网络爬虫3 - 生产者消费者模型爬取某金融网站数据

    博客首发于www.litreily.top 应一位金融圈的朋友所托,帮忙写个爬虫,帮他爬取中国期货行业协议网站中所有金融机构的从业人员信息.网站数据的获取本身比较简单,但是为了学习一些新的爬虫方法和技 ...

最新文章

  1. TOMCAT9 如何突破的双亲委派机制
  2. c语言如何发现错误在哪里,二个C语言例子,编译没通过.不知道错在哪里[求助]
  3. java小编程----最接近的三数之和
  4. 剑指offer_06
  5. mysql多数据源_egg-mysql配置多数据源
  6. OpenShift 4 之Istio-Tutorial (11) 控制Egress访问
  7. 显示1至20相同数字相乘的结果,若值比50小就不显示
  8. exploration 和 exploitation 的区别
  9. [Math] 常见的几种最优化方法
  10. hilbert谱 matlab,转 matlab 信号处理——Hilbert变换及谱分析
  11. 如何搭建自己的云盘然后进行资源共享?——可道云版
  12. 攻防世界逆向-logmein
  13. 平板电脑怎么打开HTML,为什么平板电脑和笔记本电脑打开网页不一样,感觉平板电脑就是手机?...
  14. python灰色预测_python灰度预测
  15. js的this指向总结
  16. 2k14无法打开因为计算机,NBA2K14虚拟光驱SCSI无法开启攻略_NBA2K14提示安装SPTD_快吧单机游戏...
  17. 生命与负熵---宇宙的心弦
  18. 小马虎想用计算机计算396乘19,四年级上册数学精选练习题
  19. 凤凰卫视:专业、互动、持续的云服务助力凤凰新媒体转型
  20. !!. 与 ?. 的区别

热门文章

  1. java cas logout无效_CAS logout 解决方案
  2. 卷积神经网络 (CNN) 基本原理和公式
  3. Adaboost算法的初步理解
  4. 基于Python3.6实现Java版murmurhash算法
  5. 怎么看台式计算机的屏幕大小,如何在计算机上查看显示器尺寸win10
  6. Tkinter Treeview tag_configure失效问题
  7. 数据结构(C语言严版)总结
  8. 搜狗拼音Lunix系統-乱码及繁体解决
  9. oracle之schema
  10. POJO JAVABEAN EJB的区别和联系