python多进程下的生产者和消费者模型


Posted in Python onMay 07, 2020

一、生产者消费者模型介绍

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

生产者是指生产数据的任务,消费者是指消费数据的任务。当生产者的生产能力远大于消费者的消费能力,生产者就需要等消费者消费完才能继续生产新的数据,同理,如果消费者的消费能力远大于生产者的生产能力,消费者就需要等生产者生产完数据才能继续消费,这种等待会造成效率的低下,为了解决这种问题就引入了生产者消费者模型。

1.2 如何实现生产者消费者模型

进程间引入队列可以实现生产者消费者模型,通过使用队列无需考虑锁的概念,因为进程间的通信是通过队列来实现的;

生产者生产的数据往队列里面写,消费者消费数据直接从队列里面取,这样就对实现了生产者和消费者之间的解耦。

生产者 -- >  队列  <--消费者

二、Queue实现生产者消费者模型

2.1 消费者生产者模型代码

from multiprocessing import Process, Queue
import time
 
# 消费者方法
def consumer(q, name):
  while True:
    res = q.get()
    # if res is None: break
    print("%s 吃了 %s" % (name, res))
 
# 生产者方法
def producer(q, name, food):
  for i in range(3):
    time.sleep(1) # 模拟生产西瓜的时间延迟
    res = "%s %s" % (food, i)
    print("%s 生产了 %s" % (name, res))
    # 把生产的vegetable放入到队列中
    q.put(res)
 
if __name__ == "__main__":
  #创建队列
  q = Queue()
  # 创建生产者
  p1 = Process(target=producer, args=(q, "kelly", "西瓜"))
  c1 = Process(target=consumer, args=(q, "peter",))
  p1.start()
  c1.start()
 
  # p1.join()
  # q.put(None)
  print("主进程")

2.2 执行结果

2.2.1 直接执行上面的代码的结果

直接执行会出现一个问题就是生产者生产完了,没有向消费者发送一个停止的信号,所以消费者一直会一直阻塞在q.get(),导致程序无法退出。

python多进程下的生产者和消费者模型

为了解决上面的问题,让消费者消费完了生产者的数据之后自动退出,就需要在生产者进程介绍的时候往队列里面put一个结束信号,消费者拿到这个信号,就退出消费进程。

主要是两个地方修改 ,把下方代码的注释打开就可以实现消费者消费完接收到生产者的结束信号就退出消费者进程了。

def consumer():
  if res is None: break
 
if __name__ == "__main__":
p1.join() 
q.put(None)

2.2.2 把注释打开后的运行结果

把注释打开后,消费者拿到了生产者发送的结束信号,可以正常退出程序了。

python多进程下的生产者和消费者模型

但如果有n个消费者,就需要发送n个结束信号,这种方式就不是那么简洁,像下面的代码这样:

from multiprocessing import Process, Queue
import time
 
 
# 消费者方法
def consumer(q, name):
  while True:
    res = q.get()
    if res is None: break
    print("%s 吃了 %s" % (name, res))
 
 
# 生产者方法
def producer(q, name, food):
  for i in range(3):
    time.sleep(1) # 模拟生产西瓜的时间延迟
    res = "%s %s" % (food, i)
    print("%s 生产了 %s" % (name, res))
    # 把生产的vegetable放入到队列中
    q.put(res)
 
 
if __name__ == "__main__":
  # 创建队列
  q = Queue()
  # 创建生产者
  p1 = Process(target=producer, args=(q, "kelly", "西瓜"))
  p2 = Process(target=producer, args=(q, "kelly2", "香蕉"))
  c1 = Process(target=consumer, args=(q, "peter",))
  c2 = Process(target=consumer, args=(q, "peter2",))
  c3 = Process(target=consumer, args=(q, "peter3",))
  p1.start()
  p2.start()
  c1.start()
  c2.start()
  c3.start()
 
  p1.join()
  p2.join()
  q.put(None)
  q.put(None)
  q.put(None)
  print("主进程")

其实我们现在就是生产者生产完数据之后想往队列里面发送一个结束信号,python语言提供了另外一种队列JoinableQueue([maxsize])来解决这种问题

三、JoinableQueue实现生产者消费者模型

3.1 JoinableQueue方法介绍

JoinableQueue([maxsize]) : A queue type which also supports join() and task_done() methods

q.task_done():消费者使用此方法发出信号,表示q.get()的返回项目已经被处理。

q.join():生产者调用此方法进行阻塞,直到队列中所有的项目均被处理;阻塞将持续到队列中的每个项目均调用q.task_done()方法为止。

3.2 JoinableQueue实现生产者消费者模型源码

from multiprocessing import Process,JoinableQueue
import time
 
 
# 消费者方法
def consumer(q, name):
  while True:
    res = q.get()
    if res is None: break
    print("%s 吃了 %s" % (name, res))
    q.task_done() # 发送信号给q.join(),表示已经从队列中取走一个值并处理完毕了
 
 
# 生产者方法
def producer(q, name, food):
  for i in range(3):
    time.sleep(1) # 模拟生产西瓜的时间延迟
    res = "%s %s" % (food, i)
    print("%s 生产了 %s" % (name, res))
    # 把生产的vegetable放入到队列中
    q.put(res)
  q.join() # 等消费者把自己放入队列的所有元素取完之后才结束
 
 
if __name__ == "__main__":
  # q = Queue()
  q = JoinableQueue()
  # 创建生产者
  p1 = Process(target=producer, args=(q, "kelly", "西瓜"))
  p2 = Process(target=producer, args=(q, "kelly2", "蓝莓"))
  # 创建消费者
  c1 = Process(target=consumer, args=(q, "peter",))
  c2 = Process(target=consumer, args=(q, "peter2",))
  c3 = Process(target=consumer, args=(q, "peter3",))
 
  c1.daemon = True
  c2.daemon = True
  c3.daemon = True
 
  p_l = [p1, p2, c1, c2, c3]
  for p in p_l:
    p.start()
  
  p1.join()
  p2.join()
  # 1.主进程等待p1,p2进程结束才继续执行
  # 2.由于q.join()的存在,生产者只有等队列中的元素被消费完才会结束
  # 3.生产者结束了,就代表消费者已经消费完了,也可以结束了,所以可以把消费者设置为守护进程(随着主进程的退出而退出)
 
  print("主进程")

3.3 运行结果

通过运行结果可以看出,生产者没有手动发送结束信号给消费者,而是通过JoinableQueue队列的方式也实现了生产者消费者模型。

python多进程下的生产者和消费者模型

到此这篇关于python多进程下的生产者和消费者模型的文章就介绍到这了,更多相关python多进程下的生产者和消费者内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Python 相关文章推荐
在Python的列表中利用remove()方法删除元素的教程
May 21 Python
python对excel文档去重及求和的实例
Apr 18 Python
解决python爬虫中有中文的url问题
May 11 Python
python验证码识别教程之滑动验证码
Jun 04 Python
详解Python使用Plotly绘图工具,绘制甘特图
Apr 02 Python
python文本数据处理学习笔记详解
Jun 17 Python
详解Python self 参数
Aug 30 Python
Python实现将蓝底照片转化为白底照片功能完整实例
Dec 13 Python
Python3 selenium 实现QQ群接龙自动化功能
Apr 17 Python
django数据模型中null和blank的区别说明
Sep 02 Python
Python测试框架:pytest学习笔记
Oct 20 Python
Django restful framework生成API文档过程详解
Nov 12 Python
基于python实现检索标记敏感词并输出
May 07 #Python
Python3自动生成MySQL数据字典的markdown文本的实现
May 07 #Python
如何搭建pytorch环境的方法步骤
May 06 #Python
Python基于Tkinter编写crc校验工具
May 06 #Python
使用Python实现批量ping操作方法
May 06 #Python
Python super()函数使用及多重继承
May 06 #Python
python中shell执行知识点
May 06 #Python
You might like
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
删除节点的jquery代码
2014/01/13 Javascript
通过pjax实现无刷新翻页(兼容新版jquery)
2014/01/31 Javascript
javascript实现数字验证码的简单实例
2014/02/10 Javascript
JavaScript-RegExp对象只能使用一次问题解决方法
2014/06/23 Javascript
js实现input框文字动态变换显示效果
2015/08/19 Javascript
谈谈我对JavaScript原型和闭包系列理解(随手笔记8)
2015/12/24 Javascript
jquery 无限极下拉菜单的简单实例(精简浓缩版)
2016/05/31 Javascript
ion content 滚动到底部会遮住一部分视图的快速解决方法
2016/09/06 Javascript
Javascript获取图片原始宽度和高度的方法详解
2016/09/20 Javascript
使用mint-ui开发项目的一些心得(分享)
2017/09/07 Javascript
微信小程序蓝牙连接小票打印机实例代码详解
2019/06/03 Javascript
js验证密码强度解析
2020/03/18 Javascript
JavaScript经典案例之简易计算器
2020/08/24 Javascript
echarts浮动显示单位的实现方法示例
2020/12/04 Javascript
[06:50]DSPL次级职业联赛十强晋级之路
2014/11/18 DOTA
[52:10]LGD vs Optic Supermajor小组赛D组胜者组决赛 BO3 第二场 6.3
2018/06/04 DOTA
Python语言的12个基础知识点小结
2014/07/10 Python
python3实现UDP协议的服务器和客户端
2017/06/14 Python
示例详解Python3 or Python2 两者之间的差异
2018/08/23 Python
解决python中os.listdir()函数读取文件夹下文件的乱序和排序问题
2018/10/17 Python
python_array[0][0]与array[0,0]的区别详解
2020/02/18 Python
Python logging模块原理解析及应用
2020/08/13 Python
pycharm 2020 1.1的安装流程
2020/09/29 Python
德国黑胶唱片、街头服装及运动鞋网上商店:HHV
2018/08/24 全球购物
C#如何调用Word并打开一个Word文档
2013/05/08 面试题
公益广告语集锦
2014/03/13 职场文书
喷漆工的岗位职责
2014/03/17 职场文书
应聘销售主管的求职信
2014/04/26 职场文书
感恩小明星事迹材料
2014/05/23 职场文书
优秀共产党员事迹材料
2014/12/18 职场文书
2016年小学生寒假总结
2015/10/10 职场文书
2016教师学习党章心得体会
2016/01/15 职场文书
高质量“欢迎词”
2019/04/03 职场文书
解决golang结构体tag编译错误的问题
2021/05/02 Golang
微软PC Health Check电脑健康状况检查应用下载(Win11配置检测工具)
2021/06/26 数码科技