队列&生产者消费者模型
队列
ipc机制:进程通讯
管道:pipe 基于共享的内存空间
队列:pipe+锁 queue
from multiprocessing import Process,Queue
### 案例一
q = Queue()
q.put('hyc')
q.put([1,2,4])
q.put(2)
print(q.get())
print(q.get())
print(q.get())
# q.put(5)
# q.put(5)
print(q.get()) # 默认就会一直等着拿值
此时程序运行到这里就会阻塞
from multiprocessing import Process,Queue
## 案例2
q = Queue(4)
q.put('我妻由乃')
q.put([1,2,4])
q.put('我妻善逸')
q.put(2)
q.put('乔碧萝') #队列满了的情况再放值,会阻塞
也是同理,已经设置了四个值,当放入第五个值时,就会阻塞
from multiprocessing import Process,Queue
q = Queue(3)
q.put('zhao',block=True,timeout=2) #
q.put('zhao',block=True,timeout=2) #
q.put('zhao',block=True,timeout=2) #
q.put('zhao',block=True,timeout=5) # put里的 block=True 如果满了会等待,timeout最多等待n s,如果ns还是队列还是满的就报错了
在等待5秒后会报错
from multiprocessing import Process,Queue
q = Queue()
q.put('yyyy')
q.get()
q.get(block=True,timeout=5) # block=True 阻塞等待,timeout最多等5s, 剩下同上
取值时也是同理
q = Queue(3)
q.put('qwe')
q.put('qwe')
q.put('qwe')
q.put('qwe',block=False) # 对于put来说block=False 如果队列满了就直接报错
q = Queue(3)
q.put('qwe')
q.get()
q.get(block=False)
# block = Flase 拿不到不阻塞,直接报错
当 block = Flase 时,timeout 就没有什么意义了,因为会直接报错
q = Queue(1)
q.put('123')
# q.get()
q.put_nowait('666') # block = False
q.get_nowait() # block = False
也会直接报错其实是和block = False一样的,不阻塞,有问题时直接报错
生产者和消费者模型
生产者:生产数据的任务
消费者:处理数据的任务
生产者和消费者的关系:生产者--队列(盆)-->消费者
生产者可以不停的生产,达到了自己最大的生产效率,消费者可以不停的消费,也达到了自己最大的消费效率.
生产者消费者模型大大提高了生产者生产的效率和消费者消费的效率.
from multiprocessing import Process, Queue
def producer(q,name,food):
'''生产者'''
for i in range(10):
print(f'{name}生产了{food}{i}')
res = f'{food}{i}'
q.put(res)
q.put(None)
def consumer(q,name):
'''消费者'''
while True:
res = q.get(timeout=5)
if res is None:break
print(f'{name}吃了{res}')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer,args=(q,'rocky','包子'))
c1 = Process(target=consumer,args=(q,'成哥'))
p1.start()
c1.start()
这就是最简单的生产者和消费者模型了,他的作用是每次生产者都会生产物品,当生产者生产完10个包子的时候,跳出for循环,最后放入一个None。随后当消费者接收到None的时候,就会被break掉。
在一个生产者对上一个消费者的时候,这个方法是可行的。但是当多个生产者对一个消费者的时候,其中一名生产者先生产完了食物并放入None,但是第二名生产者还没有生产完的话,消费者却已经收到了第一个生产者的None。这样的话会出现问题,所以我们可以改变一下思路,把None放到外面
from multiprocessing import Process,Queue
import time,random
def producer(q,name,food):
'''生产者'''
for i in range(3):
print(f'{name}生产了{food}{i}')
time.sleep(random.randint(1, 3))
res = f'{food}{i}'
q.put(res)
# q.put(None)
def consumer(q,name):
'''消费者'''
while True:
res = q.get(timeout=5)
if res is None:break
time.sleep(random.randint(1,3))
print(f'{name}吃了{res}')
if __name__ == '__main__':
q = Queue()
p1 = Process(target=producer,args=(q,'rocky','包子'))
p2 = Process(target=producer,args=(q,'mac','韭菜'))
p3 = Process(target=producer,args=(q,'nick','蒜泥'))
c1 = Process(target=consumer,args=(q,'成哥'))
c2 = Process(target=consumer,args=(q,'浩南哥'))
p1.start()
p2.start()
p3.start()
c1.start()
c2.start()
p1.join()
p2.join()
p3.join() # 生产者生产完毕
q.put(None)# 几个消费者put几次
q.put(None)
但是用这种方法就会出现新的问题,因为消费者方法用的是while True,他是不会停下的。所以我们就要用到之前学过的守护进程:
from multiprocessing import Process,Queue,JoinableQueue
import time,random
def producer(q,name,food):
'''生产者'''
for i in range(3):
print(f'{name}生产了{food}{i}')
time.sleep(random.randint(1, 3))
res = f'{food}{i}'
q.put(res)
# q.put(None)
def consumer(q,name):
'''消费者'''
while True:
res = q.get()
# if res is None:break
time.sleep(random.randint(1,3))
print(f'{name}吃了{res}')
q.task_done() #
if __name__ == '__main__':
q = JoinableQueue()
p1 = Process(target=producer,args=(q,'rocky','包子'))
p2 = Process(target=producer,args=(q,'mac','韭菜'))
p3 = Process(target=producer,args=(q,'nick','蒜泥'))
c1 = Process(target=consumer,args=(q,'成哥'))
c2 = Process(target=consumer,args=(q,'浩南哥'))
p1.start()
p2.start()
p3.start()
c1.daemon = True
c2.daemon = True
c1.start()
c2.start()
p1.join()
p2.join()
p3.join() # 生产者生产完毕
# q.put(None)# 几个消费者put几次
# q.put(None)
q.join() # 分析
# 生产者生产完毕--这是主进程最后一行代码结束--q.join()消费者已经取干净了,没有存在的意义了.
#这是主进程最后一行代码结束,消费者已经取干净了,没有存在的意义了.守护进程的概念.
joinableQueue
from multiprocessing import Process,Queue,JoinableQueue
q = JoinableQueue()
q.put('zhao') # 放队列里一个任务
q.put('qian')
print(q.get())
q.task_done() # 完成了一次任务
print(q.get())
q.task_done() # 完成了一次任务
q.join() #计数器不为0的时候 阻塞等待计数器为0后通过
# 想象成一个计数器 :put +1 task_done -1
队列&生产者消费者模型的更多相关文章
- #queue队列 #生产者消费者模型
#queue队列 #生产者消费者模型 #queue队列 #有顺序的容器 #程序解耦 #提高运行效率 #class queue.Queue(maxsize=0) #先入先出 #class queue.L ...
- Day034--Python--锁, 信号量, 事件, 队列, 生产者消费者模型, joinableQueue
进程同步: 1. 锁 (重点) 锁通常被用来实现对共享资源的同步访问.为每一个共享资源创建一个Lock对象,当你需要访问该资源时,调用acquire方法来获取锁对象(如果其它线程已经获得了该锁, ...
- python 全栈开发,Day39(进程同步控制(锁,信号量,事件),进程间通信(队列,生产者消费者模型))
昨日内容回顾 python中启动子进程并发编程并发 :多段程序看起来是同时运行的ftp 网盘不支持并发socketserver 多进程 并发异步 两个进程 分别做不同的事情 创建新进程join :阻塞 ...
- 5 并发编程-(进程)-队列&生产者消费者模型
1.队列的介绍 进程彼此之间互相隔离,要实现进程间通信(IPC),multiprocessing模块支持两种形式:队列和管道,这两种方式都是使用消息传递的 创建队列的类(底层就是以管道和锁定的方式实现 ...
- python2.0_s12_day9之day8遗留知识(queue队列&生产者消费者模型)
4.线程 1.语法 2.join 3.线程锁之Lock\Rlock\信号量 4.将线程变为守护进程 5.Event事件 * 6.queue队列 * 7.生产者消费者模型 4.6 queue队列 que ...
- python网络编程--进程(方法和通信),锁, 队列,生产者消费者模型
1.进程 正在进行的一个过程或者说一个任务.负责执行任务的是cpu 进程(Process: 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础.在 ...
- Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)
Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...
- 网络编程基础----并发编程 ---守护进程----同步锁 lock-----IPC机制----生产者消费者模型
1 守护进程: 主进程 创建 守护进程 辅助主进程的运行 设置进程的 daemon属性 p1.daemon=True 1 守护进程会在主进程代码执行结束后就终止: 2 守护进程内无法再开启子进程 ...
- 守护进程,进程安全,IPC进程间通讯,生产者消费者模型
1.守护进程(了解)2.进程安全(*****) 互斥锁 抢票案例3.IPC进程间通讯 manager queue(*****)4.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...
随机推荐
- MongoDB自建和阿里云RDS备份还原
MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用提供可扩展的高性能数据存储解决方案. MongoDB是一个介于关系数据库和非关系数据库之间的产品,是非关系数据库当中功 ...
- lua程序设计(一)
摘要:lua程序设计第二版学习笔记 脚本语言的基础语法大都比较简单,这里只列举一些lua独有,或者需要特别注意的语法点. 书中前三章的内容是一些惯常的引言,基础数据类型,运算符等内容,相对简单,这里就 ...
- NOIP模拟测试8反思
被动态逆序对戏耍,来写博客这次考试油炸了 模板爆零,哈希调半天导致T3没时间,我都干了些什么&_& T3思路: 利用环的性质先拼成一条链,然后二分边界. 证明就不说啦(其实是我不会) ...
- My Android 学习之旅--开始
其实,很早就想写写博客了,一直懒到现在. 学习android也不是今天才开始的,大概在2月份过完年之后就开始了,买了我认为还可以的书<Android从入门到精通>,花了不到一个月的时间,把 ...
- Project Euler 59: XOR decryption
计算机上的每个字母都对应一个独特的编号,普遍接受的标准是ASCII(美国信息交换标准代码).例如,大写字母的A的ASCII码是65,星号(*)的ASCII码是42,而小写字母k的代码是107. 一种现 ...
- egret Tiledmap编写障碍物的思路
egret Tiledmap编写障碍物的思路 获取控制对象下一刻移动的坐标,将其转换成瓦片坐标,如果getTileGIDAt(根据瓦片坐标获取瓦片id)的值不为0,说明对象将要移动的位置有障碍物,不做 ...
- Ember.js和Vue.js对比,哪个框架更优秀?
本文由葡萄城技术团队于博客园翻译并首发 转载请注明出处:葡萄城官网,葡萄城为开发者提供专业的开发工具.解决方案和服务,赋能开发者. JavaScript最初是为Web应用程序创建的.但是随着前端技术的 ...
- 对于 TCP 三次握手的理解
假设名叫 A 和 B 的两个人要进行通信,那么他们两人之间,首先要确保通信顺畅. 而确保通信顺畅,就要从 3 个维度,确定 8 个能力 3 个维度分别是: 1.人知道(A 知道.B 知道) 2.人(A ...
- 0x8000FFFF 错误的解决方式
问题描述: 在F盘新建文件夹或文件的时候提示0x8000FFFF灾难性错误: 解决方法: 1.在F盘的位置,右击选择属性 2.在弹出的窗口中选择工具,点击检查 3.根据系统提示进行响应的驱动扫描与修复 ...
- 百度全景地图使用时提示flash版本过低 如何处理?
从Chrome 69.0 版本起,Flash权限受到进一步限制,默认仅在当前浏览器会话有效.关闭Enable Ephemeral Flash Permissions ,才能看到 “Add”按钮.解决方 ...