队列&生产者消费者模型
队列
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.生产者消费者模型 守护进程 指的也是一个进程,可以守护着另一个进程 一 ...
随机推荐
- 使用asp.net core 3.0 搭建智能小车2
上一篇中我们把基本的运行环境搭建完成了,这一篇中,我们实战通过树莓派B+连接HC-SR04超声波测距传感器,用c# GPIO控制传感器完成距离测定,并将距离显示在网页上. 1.HC-SR04接线 传感 ...
- 《Effective Java》 读书笔记(五)使用依赖注入取代原本的资源依赖
相信接触过Spring的同学,对于依赖注入并不陌生. 刚开始在听说这个名字的时候,一直不明白到底什么叫依赖注入,后来才发现,依赖注入一直都存在我们日常代码中,只是我们没有刻意的把它提出来,然后再取这样 ...
- Redis开发与运维:SDS
STRING 我们会经常打交道的string类型,在redis中拥有广泛的使用.也是开启redis数据类型的基础. 在我最最开始接触的redis的时候,总是以为字符串类型就是值的类型是字符串. 比如: ...
- JavaSE语法
二.JavaSE语法(上) 1.Java 有没有 goto 语句? goto 是 Java 中的保留字,在目前版本的 Java 中没有使用.根据 James Gosling(Java 之父)编写的&l ...
- 【控制系统数字仿真与CAD】实验一:状态方程、传函为模型的系统的仿真
一.实验目的 1. 掌握各数学模型之间的转换与数学模型的参数获取,掌握相关MATLAB命令 2. 掌握欧拉法和RK法的递推公式 3. 掌握欧拉法和RK法的MATLAB算法实现 二.实验内容 1. 分别 ...
- java数组、字符串拼接
1. 数组实现拼接 int[] arr ={11,22,33,44,55,66}; System.out.print("["); for (int i = 0; i <arr ...
- php imagick生成图片需要注意的问题
php imagick生成图片需要注意的问题 坐标必须写死不要写自适应 这样才能达到效果图的最好效果 而且不会出现各种问题如果前端显示的生成图片不达标 可以再写一套代码 把后台生成的图片透明度设成0 ...
- C#语音特性 很实用
1.隐式类型 Var 2.匿名类型 new{} 3.自动属性 [prop TAB] public string Title { get; set; } 4.初始化器 var myObj1 = ne ...
- nyoj 975-关于521 (EOF)
975-关于521 内存限制:64MB 时间限制:1000ms 特判: No 通过数:5 提交数:46 难度:2 题目描述: Acm队的流年对数学的研究不是很透彻,但是固执的他还是想一头扎进去. 浏览 ...
- PL真有意思(二):程序设计语言语法
前言 虽然标题是程序语言的语法,但是讲的是对词法和语法的解析,其实关于这个前面那个写编译器系列的描述会更清楚,有关语言语法的部分应该是穿插在整个设计当中的,也看语言设计者的心情了 和英语汉语这些自然语 ...