114 Python程序中的进程操作-进程间通信(multiprocess.Queue)
目录
- 一、进程间通讯
- 二、队列
- 2.1 概念介绍---multiprocessing.Queue
- 2.2 方法介绍
- 2.3 其他方法(了解)
- 三、Queue队列-实例演示
- 3.1 但看队列用法
- 3.2 子进程发送数据给父进程
- 四、生产者消费者模型
- 4.1 为什么要使用生产者和消费者模式
- 4.2 什么是生产者消费者模式
- 4.3 基于队列实现生产者消费者模型
- 五、 JoinableQueue队列
- 5.1 JoinableQueue的使用
- 5.2 通过JoinableQueue队列实现生产者消费者模型
一、进程间通讯
IPC。就是多个进程间相互通讯。进程间通讯并不只是单个语言的问题。而是每个语言都有的。实现进程间通讯有很多。C语言中有:管道:pipe(匿名管道),有名管道、信号、共享内存、消息队列、信号量等等
Python中这里通过队列实现进程间通讯
二、队列
2.1 概念介绍---multiprocessing.Queue
创建共享的进程队列,Queue是多进程安全的队列,可以使用Queue实现多进程之间的数据传递。
Queue([maxsize])
创建共享的进程队列。
参数 :maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。
底层队列使用管道和锁定实现。
2.2 方法介绍
Queue([maxsize])
:创建共享的进程队列。maxsize是队列中允许的最大项数。如果省略此参数,则无大小限制。底层队列使用管道和锁定实现。另外,还需要运行支持进程以便队列中的数据传输到底层管道中。
Queue的实例q具有以下方法:
q.get( [ block [ ,timeout ] ] )
:返回q中的一个项目。如果q为空,此方法将阻塞,直到队列中有项目可用为止。block用于控制阻塞行为,默认为True. 如果设置为False,将引发Queue.Empty异常(定义在Queue模块中)。timeout是可选超时时间,用在阻塞模式中。如果在制定的时间间隔内没有项目变为可用,将引发Queue.Empty异常。
q.get_nowait()
:同q.get(False)
方法。
q.put(item [, block [,timeout ] ] )
:将item放入队列。如果队列已满,此方法将阻塞至有空间可用为止。block控制阻塞行为,默认为True。如果设置为False,将引发Queue.Empty异常(定义在Queue库模块中)。timeout指定在阻塞模式中等待可用空间的时间长短。超时后将引发Queue.Full异常。
q.qsize()
:返回队列中目前项目的正确数量。此函数的结果并不可靠,因为在返回结果和在稍后程序中使用结果之间,队列中可能添加或删除了项目。在某些系统上,此方法可能引发NotImplementedError异常。
q.empty()
:如果调用此方法时 q为空,返回True。如果其他进程或进程正在往队列中添加项目,结果是不可靠的。也就是说,在返回和使用结果之间,队列中可能已经加入新的项目。
q.full()
:如果q已满,返回为True. 由于进程的存在,结果也可能是不可靠的(参考q.empty()
方法)。
2.3 其他方法(了解)
q.close()
:关闭队列,防止队列中加入更多数据。调用此方法时,后台进程将继续写入那些已入队列但尚未写入的数据,但将在此方法完成时马上关闭。如果q被垃圾收集,将自动调用此方法。关闭队列不会在队列使用者中生成任何类型的数据结束信号或异常。例如,如果某个使用者正被阻塞在get()
操作上,关闭生产者中的队列不会导致get()
方法返回错误。
q.cancel_join_thread()
:不会再进程退出时自动连接后台进程。这可以防止join_thread()
方法阻塞。
q.join_thread()
:连接队列的后台进程。此方法用于在调用q.close()
方法后,等待所有队列项被消耗。默认情况下,此方法由不是q的原始创建者的所有进程调用。调用q.cancel_join_thread()
方法可以禁止这种行为。
三、Queue队列-实例演示
3.1 但看队列用法
'''
ipc 进程间通讯。使用队列实现
管道:pipe 基于共享的内存空间
队列:pipe+锁 Queue
put:放(可以设置阻塞非阻塞,和等待时间)
get:取(可以设置阻塞非阻塞,和等待时间)
'''
### 语法
q = Queue(3) # 创建队列, 可以设置最大值
## put 放
q.put('你好') # 往队列中放入值,可以设置阻塞和等待时间,默认:满了再放就会阻塞等待
q.put([1,2,4])
q.put(2)### 不设置等待时间,队列满了继续放
# q.put(5) # 阻塞,队列满了,等待队列空了就放进去## get 拿
print(q.get()) # 获取队列中的内容,可以设置阻塞和等待时间,默认:拿不到内容就会阻塞等待
print(q.get())
print(q.get())### 不设置等待时间
# print(q.get()) # 阻塞,一直等待获取队列内容### 设置等待时间
# print(q.get(timeout=2)) # 等两秒,等不到就报错
# q.put(88,timeout=2) # 不会报错,因为队列中没内容### 全都设置非阻塞模式
q = Queue(3) # 创建队列, 可以设置最大值
q.put('你好', block=False) # 设置非阻塞,如果满了再放就会报错
q.put([1,2,4], block=False)
q.put(2, block=False)
# q.put(4, block=False) # 报错,队列满了# q.put_nowait('666') # 等同 block = False,报错,队列满了
3.2 子进程发送数据给父进程
import time
from multiprocessing import Process, Queuedef f(q):q.put([time.asctime(), 'from Eva', 'hello']) #调用主函数中p进程传递过来的进程参数 put函数为向队列中添加一条数据。if __name__ == '__main__':q = Queue() #创建一个Queue对象p = Process(target=f, args=(q,)) #创建一个进程p.start()print(q.get())p.join()
上面是一个queue的简单应用,使用队列q对象调用get函数来取得队列中最先进入的数据。 接下来看一个稍微复杂一些的例子:批量生产数据放入队列再批量获取结果。
四、生产者消费者模型
在并发编程中使用生产者和消费者模式能够解决绝大多数并发问题。该模式通过平衡生产进程和消费进程的工作能力来提高程序的整体处理数据的速度。
4.1 为什么要使用生产者和消费者模式
在进程世界里,生产者就是生产数据的进程,消费者就是消费数据的进程。在多进程开发当中,如果生产者处理速度很快,而消费者处理速度很慢,那么生产者就必须等待消费者处理完,才能继续生产数据。同样的道理,如果消费者的处理能力大于生产者,那么消费者就必须等待生产者。为了解决这个问题于是引入了生产者和消费者模式。
4.2 什么是生产者消费者模式
生产者消费者模式是通过一个容器来解决生产者和消费者的强耦合问题。生产者和消费者彼此之间不直接通讯,而通过阻塞队列来进行通讯,所以生产者生产完数据之后不用等待消费者处理,直接扔给阻塞队列,消费者不找生产者要数据,而是直接从阻塞队列里取,阻塞队列就相当于一个缓冲区,平衡了生产者和消费者的处理能力。
4.3 基于队列实现生产者消费者模型
ef producer(q,name,food):'''生产者'''for i in range(10):print(f'{name}生产了{food}{i}')res = f'{food}{i}'q.put(res)def consumer(q,name):'''消费者'''while 1:res = q.get()if res == None:breakprint(f'{name}买了{res}')if __name__ == '__main__':q = Queue() # 使用队列p1 = Process(target=producer,args=(q,"xc","意大利面"))c1 = Process(target=consumer,args=(q,"haha"))p2 = Process(target=producer, args=(q, "xc", "牛肉"))c2 = Process(target=consumer, args=(q, "xixi"))p3 = Process(target=producer, args=(q, "xc", "可乐"))p1.start()c1.start()p2.start()c2.start()p3.start()p1.join() # 等待生产者结束p2.join() # 等待生产者结束p3.join() # 等待生产者结束q.put(None) # 有几个消费者就要发几个None,让 子进程收到None就结束q.put(None) # 有几个消费者就要发几个None,让 子进程收到None就结束
结束信号None,不一定要由生产者发,主进程里同样可以发,但主进程需要等生产者结束后才应该发送该信号。 有几个消费者就要发几个None,让 子进程收到None就结束
五、 JoinableQueue队列
JoinableQueue队列就对Queue队列的改良版,加入了类似信号量的机制。
5.1 JoinableQueue的使用
语法:
- 实例化对象:
q = JoinableQueue()
- 向队列中放入内容,相当于 信号量+1 操作:
q.put(xxx)
- 从队列中取出内容:
q.get()
- 任务结束,相当于 信号量-1 操作:
q.task_done()
- 当这个 信号量不为0时,会阻塞等待,计数器为0后通过。
实例:
# JoinableQueue的使用
q = JoinableQueue()q.put('1') # +1
q.put('2') # +1print(q.get())
q.task_done() # -1
print(q.get())
q.task_done() # -1
q.join() #计数器不为0会阻塞等待 计数器为0后通过
5.2 通过JoinableQueue队列实现生产者消费者模型
def producer(q, name, food):'''生产者'''for i in range(10):print(f'{name}生产了{food}{i}')res = f'{food}{i}'q.put(res) # +1def consumer(q, name):'''消费者'''while 1:res = q.get()if res == None:breakprint(f'{name}买了{res}')q.task_done()if __name__ == '__main__':q = JoinableQueue() # 使用加了join的队列p1 = Process(target=producer, args=(q, "xc", "意大利面"))c1 = Process(target=consumer, args=(q, "haha"))p2 = Process(target=producer, args=(q, "xc", "牛肉"))c2 = Process(target=consumer, args=(q, "xixi"))p3 = Process(target=producer, args=(q, "xc", "可乐"))# 把消费者变成守护进程,主进程结束,子进程就结束c1.daemon = True # 进程结束,子进程就结束c2.daemon = True # 进程结束,子进程就结束p1.start()c1.start()p2.start()c2.start()p3.start()p1.join() # 等待生产者结束p2.join() # 等待生产者结束p3.join() # 等待生产者结束
上述代码中,是通过将子进程变为守护进程,在消费者的子进程中每次收到消息都task_done,然后等待主进程结束,直接结束子进程。
转载于:https://www.cnblogs.com/XuChengNotes/p/11529601.html
114 Python程序中的进程操作-进程间通信(multiprocess.Queue)相关推荐
- 在python程序中的进程操作
********在python程序中的进程操作********之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了, 运行中的程序就是一个进程.所有的进程都是通过 ...
- python在中小学教学中的应用-在python程序中的进程操作
********在python程序中的进程操作********之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了, 运行中的程序就是一个进程.所有的进程都是通过 ...
- python启动多个进程_Python程序中的进程操作--—--开启多进程
Python程序中的进程操作-----开启多进程 之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创 ...
- python打开一个软件并进行操作_python程序中的进程操作
之前我们已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,刚刚我们已经了解了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序也是一个进程 ...
- python进程数据共享_python程序中的进程操作-进程间的数据共享
展望未来,基于消息传递的并发编程是大势所趋 即便是使用线程,推荐做法也是将程序设计为大量独立的线程集合,通过消息队列交换数据. 这样极大地减少了对使用锁定和其他同步手段的需求,还可以扩展到分布式系统中 ...
- Python程序中的线程操作-锁
目录 一.同步锁 1.1 多个线程抢占资源的情况 1.1.1 对公共数据的操作 1.2 同步锁的引用 1.3 互斥锁与join的区别 二.死锁与递归锁 2.1 死锁 2.2 递归锁RLock 三.典型 ...
- python中flush怎么用,在Python程序中操作文件之flush()方法的使用教程
在Python程序中操作文件之flush()方法的使用教程 flush()方法刷新内部缓冲区,像标准输入输出的fflush.这类似文件的对象,无操作. Python关闭时自动刷新文件.但是可能要关闭任 ...
- 微课系列(7):Python程序中sys.argv的用法
技术要点: 1)Python程序中如果使用到了sys.argv,这样的程序一般需要在命令提示符环境中运行,而不是在Python开发环境直接中运行. 2)sys.argv是个包含若干字符串的列表,其中s ...
- 如何在Python程序中运行Unix命令
Unix是由Ken Thompson和Dennis Ritchie在1969年左右在AT&T贝尔实验室开发的操作系统. 我们可以使用许多有趣的Unix命令来执行不同的任务. 问题是,我们可以直 ...
- 关于python缩进的描述中_关于Python程序中与“缩进”有关的说法中,以下选项中正确的是()...
关于Python程序中与"缩进"有关的说法中,以下选项中正确的是() 答:缩进在程序中长度统一且强制使用 同文学或同音乐主题的民歌,<_______>是其中之一.此曲经 ...
最新文章
- pvrect r语言 聚类_R语言一条命令实现基于样本和距离的聚类分析
- Linux内核中工作队列的使用work_struct,delayed_work
- 3.6 mkpasswd命令
- [MATLAB学习笔记]view相机视角
- 第三次学JAVA再学不好就吃翔(part28)--猜数字小游戏
- Shank的大步小步算法(Shank‘s Baby-Step-Giant-Step Algorithm)
- cocoapods安装bug
- Maven中几张重要的总结图
- Eclipse中Java Web开发插件安装
- android触摸事件触摸点坐标,Android开发——触摸事件TouchEvent详解及其应用
- mysql课件_MYSQL讲课时的PPT课件.ppt
- Windows Phone 7 软件体系结构
- Java 实现视频裁剪(附代码) | Java工具类
- 01--QT GUI视频教程
- Maxon伺服驱动EPOS2 24/5 配置
- 应聘的16个经典面试问题回答思路
- 在Qt中如何用纯代码写一个本地视频播放器
- 医疗器械网电源部分使用一个保险丝还是两个保险丝?
- python体测成绩数据分析_Django xadmin 体测成绩管理平台总结
- jQuery制作照片墙
热门文章
- 数据结构和算法——中序线索化二叉树
- Python语法学习第三天--元组
- 多线程测试时的辅助类--CountDownLatch
- Stream流的使用函数式接口
- 阿里云mysql远程连接_阿里云从0安装mysql到远程连接
- java基础总结06-常用api类-BigDecimal-精确计算
- javascript 图解 event对象offsetX, clientX, pageX, screenX, layerX, x区别
- java镜像_012 制作Java基础镜像
- spring第二冲刺阶段第七天
- git 小札 - 流程总览