队列&生产者消费者模型
队列
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.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...
随机推荐
- Python 图形验证码库、二维码库的使用
1. 图形验证码库 captcha # 引入图形库 from captcha.image import ImageCaptcha # 获取图像对象 image = ImageCaptcha(width ...
- st表、树状数组与线段树 笔记与思路整理
已更新(2/3):st表.树状数组 st表.树状数组与线段树是三种比较高级的数据结构,大多数操作时间复杂度为O(log n),用来处理一些RMQ问题或类似的数列区间处理问题. 一.ST表(Sparse ...
- NOIP模拟 23
曾经有一段真挚的AK摆在skyh面前,但他一直意淫自己AK导致没有AK. 如果非要把这AK加一个期限的话,skyh一辈子都AK不了了. 论爆零选手的爆零原因 我说T3想到了能AC的思路但是爆零了有人同 ...
- Redis性能解析--Redis为什么那么快?
echo编辑整理,欢迎转载,转载请声明文章来源.欢迎添加echo微信(微信号:t2421499075)交流学习. 百战不败,依不自称常胜,百败不颓,依能奋力前行.--这才是真正的堪称强大!!! Red ...
- ASP.NET Core主机地址过滤HostFiltering
前言 在ASP.Net Core2.X调用的CreateWebHostBuilder和3.X的主要区别在于WebHost的调用,CreateDefaultBuilder被Host替换,另一个区别是对C ...
- linux 自启动 | 三种方式自启动
linux 实现自启动有多种方式,通过Linux 底层启动原理介绍,便可以理解以下几种方式 这里简单介绍一下这几种方式 一.自定义开机程序 /etc/rc.d/rc.local 1.vim / ...
- vmware centos共享文件夹
vmware centos共享文件夹 查看VMware Tools 是否安装成功 <pre>vmware-hgfsclient</pre> 出现共享文件夹<pre> ...
- python中字符串常见操作(二)
# 可迭代对象有:字典,列表,元组,字符串,集合 str1 = '192.168.1.1' str2 = 'as df gh jk' str3 = '小李子' str4 = ['aa','bb','c ...
- Hibernate的多对多关系
1.表的关系: 分别有三个表:课程表.学生表.分数表.课程和学生的关系是多对多的,因为一个学生对应多个课程,而一个课程被多个学生选修.如果用一对多.多对一的观点来看待课程和学生的关系显然是不对的,因为 ...
- WPF CefSharp 爬虫
1.实际需求 EMS邮件的自动分拣,要分拣首先需要获取邮件的面单号和邮寄地址,现在我们的快递一般都有纸质面单的,如果是直接使用图像识别技术从纸质面单中获取信息,这个开发的成本和实时性 ...