Python multiprocessing

推荐教程
- 官方文档
- multiprocess各个模块较详细介绍
- 廖雪峰教程--推荐
- Pool中apply, apply_async的区别联系
- (推荐)python多进程的理解 multiprocessing Process join run
multiprocessing.Manager.Queuue vs multiprocessing.Queuue
队列 | 说明 |
---|---|
multiprocessing.Queuue | 只应通过继承在进程之间共享 Queue 对象 |
multiprocessing.Manager.Queue | 如上所述,在进行并发编程时,通常最好尽量避免使用共享状态。使用多个进程时尤其如此。但是,如果您确实需要使用某些共享数据,那么多处理提供了两种方法。其中一种就是使用Manager |
范例一
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2019-03-09 17:24
# @Author : wangbin
# @FileName: demo06.py
# @mail : bupt_wangbin@163.com
from multiprocessing import Process, Queue, Pool, Manager
import os
import time
import random
def write(q):
# 写数据进程执行的代码:
print('Process to write: %s' % os.getpid())
for value in range(8):
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
def read(q):
# 读数据进程执行的代码:
print('Process to read: %s' % os.getpid())
while True:
if not q.empty():
value = q.get(True)
print('Get %s from queue.' % value)
time.sleep(random.random())
else:
break
if __name__ == '__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
p = Pool()
pw = Process(target=write, args=(q,))
pw.start()
time.sleep(0.5)
pr = p.apply(read, args=(q,))
p.close()
p.join()
pw.join()
报错: Queue objects should only be shared between processes through inheritance(只应通过继承在进程之间共享 Queue 对象, 即为只可以父进程和子进程之间共享 Queue 对象)

范例二
一下方式可以使用
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2019-03-09 15:45
# @Author : wangbin
# @FileName: demo04.py
# @mail : bupt_wangbin@163.com
"""
进程间通信
Process之间肯定是需要通信的,操作系统提供了很多机制来实现进程间的通信。
Python的multiprocessing模块包装了底层的机制,提供了Queue、Pipes等多种方式来交换数据。
我们以Queue为例,在父进程中创建两个子进程,一个往Queue里写数据,一个从Queue里读数据:
"""
from multiprocessing import Process, Queue, Pool, Manager
import os
import time
import random
def write(q):
# 写数据进程执行的代码:
print('Process to write: %s' % os.getpid())
for value in range(10):
# print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
def read(q):
# 读数据进程执行的代码:
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)
if __name__ == '__main__':
# 父进程创建Queue,并传给各个子进程:
q = Queue()
pw = Process(target=write, args=(q,))
pr1 = Process(target=read, args=(q,))
pr2 = Process(target=read, args=(q,))
# 启动子进程pw,写入:
pw.start()
# 启动子进程pr,读取:
pr1.start()
pr2.start()
# 等待pw结束:
pw.join()
# pr进程里是死循环,无法等待其结束,只能强行终止:
pr1.terminate()
pr2.terminate()
上述程序由于都是死循环, pr1 和 pr2如果有一个调用 join 方法的话, 程序就会一直在 block 住. 如果使用 Pool 会比较好管理, 而之前第一个范例说明, Pool 与 Produce 之间使用 multiprocessing.Queue 会出现错误, 所以, 如果使用 Pool 来产生多个进程用于生产者或者消费者, 用 Pool 很简单. 所以, 当要共享数据时候, 使用Manager.Queue() 准没错
总结: 如果使用进程共享数据的话, 就使用 Manager.Queue()
范例三
下面是使用进程池来做的
#!/usr/bin/python3
# -*- coding: utf-8 -*-
# @Time : 2019-03-09 15:45
# @Author : wangbin
# @FileName: demo04.py
# @mail : bupt_wangbin@163.com
from multiprocessing import Process, Queue, Pool, Manager
import os
import time
import random
def write(q):
# 写数据进程执行的代码:
print('Process to write: %s' % os.getpid())
for value in range(3):
print('Put %s to queue...' % value)
q.put(value)
time.sleep(random.random())
def read(q):
# 读数据进程执行的代码:
print('Process to read: %s' % os.getpid())
while True:
value = q.get(True)
print('Get %s from queue.' % value)
if __name__ == '__main__':
# 父进程创建Queue,并传给各个子进程:
with Manager() as manager:
with Pool(processes=8) as pool:
# 启动子进程pr,读取:
q = manager.Queue()
for i in range(3):
pool.apply_async(func=write, args=(q,))
pool.apply_async(func=read, args=(q,)).get()
pool.close()
pool.join()
pool.terminate()

由此可以看出, 每个进程中, 每个程序都会跑一边. 所以炼丹测试时, 验证集数据集只能使用一个进程跑, 而读取的进程需要多设置几个
Pool
如果要启动大量的子进程,可以用进程池的方式批量创建子进程:
from multiprocessing import Pool
import os, time, random
def long_time_task(name):
print('Run task %s (%s)...' % (name, os.getpid()))
start = time.time()
time.sleep(random.random() * 3)
end = time.time()
print('Task %s runs %0.2f seconds.' % (name, (end - start)))
if __name__=='__main__':
print('Parent process %s.' % os.getpid())
p = Pool(4)
for i in range(5):
p.apply_async(long_time_task, args=(i,))
print('Waiting for all subprocesses done...')
p.close()
p.join()
print('All subprocesses done.')
执行结果如下:
Parent process 669.
Waiting for all subprocesses done...
Run task 0 (671)...
Run task 1 (672)...
Run task 2 (673)...
Run task 3 (674)...
Task 2 runs 0.14 seconds.
Run task 4 (673)...
Task 1 runs 0.27 seconds.
Task 3 runs 0.86 seconds.
Task 0 runs 1.41 seconds.
Task 4 runs 1.91 seconds.
All subprocesses done.
代码解读:
对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),调用close()之后就不能继续添加新的Process了。
请注意输出的结果,task 0,1,2,3是立刻执行的,而task 4要等待前面某个task完成后才执行,这是因为Pool的默认大小在我的电脑上是4,因此,最多同时执行4个进程。这是Pool有意设计的限制,并不是操作系统的限制。如果改成:p = Pool(5), 就可以同时跑5个进程。
由于Pool的默认大小是CPU的核数,如果你不幸拥有8核CPU,你要提交至少9个子进程才能看到上面的等待效果。
Python multiprocessing的更多相关文章
- python multiprocessing example
python multiprocessing example Server Code: #!/usr/bin/python #-*- coding: UTF-8 -*- # mpserver.py # ...
- python MultiProcessing模块进程间通信的解惑与回顾
这段时间沉迷MultiProcessing模块不能自拔,没办法,python的基础不太熟,因此就是在不断地遇到问题解决问题.之前学习asyncio模块学的一知半解,后来想起MultiProcessin ...
- python multiprocessing模块
python multiprocessing模块 原文地址 multiprocessing multiprocessing支持子进程.通信和共享数据.执行不同形式的同步,提供了Process.Queu ...
- python multiprocessing.Process
在使用Kafka-python时自己写的一个bug 我在一个进程的__init__中初始化了一个producer,但是一直不好用 但是在函数里直接new一个就好用了 why? 需要说明的是produc ...
- python MultiProcessing标准库使用Queue通信的注意要点
今天原本想研究下MultiProcessing标准库下的进程间通信,根据 MultiProcessing官网 给的提示,有两种方法能够来实现进程间的通信,分别是pipe和queue.因为看queue顺 ...
- python multiprocessing深度解析
在写python多线程代码的时候,会用到multiprocessing这个包,这篇文章总结了一些这个包在多进程管理方面的一些原理和代码分析. 1. 问题一:是否需要显式调用pool的close和joi ...
- Python multiprocessing模块的Pool类来代表进程池对象
#-*-coding:utf-8-*- '''multiprocessing模块提供了一个Pool类来代表进程池对象 1.Pool可以提供指定数量的进程供用户调用,默认大小是CPU的核心数: 2.当有 ...
- python Multiprocessing 多进程应用
在运维工作中,经常要处理大量数据,或者要跑一些时间比较长的任务,可能都需要用到多进程,不管是管理端下发任务,还是客户端执行任务,如果服务器配置还可以,跑多进程还是挺能解决问题的 Multiproces ...
- python multiprocessing.Pool 中map、map_async、apply、apply_async的区别
multiprocessing是python的多进程库,multiprocessing.dummy则是多线程的版本,使用都一样. 其中都有pool池的概念,进程池/线程池有共同的方法,其中方法对比如下 ...
随机推荐
- Nonlinear Component Analysis as a Kernel Eigenvalue Problem
目录 引 kernel PCA kernel 的选择 性质 一些问题 代码 Scholkopf B, Smola A J, Muller K, et al. Nonlinear component a ...
- iview render Datepicker 起止时间限制
{ title: '开始时间', key: 'planDateFrom', minWidth: 120, sortable: true, align: 'center', render: (h, pa ...
- docker企业实战视频教程
Docker是一个开源的引擎,可以轻松的为任何应用创建一个轻量级的.可移植的.自给自足的容器.开发者在笔记本上编译测试通过的容器可以批量地在生产环境中部署,包括VMs(虚拟机).bare metal. ...
- PL2303HX在Windows 10下面不装安装驱动的解决办法(Code:10)
Prolific在很早之前推出了一款名为PL2303HX的芯片, 用于USB转RS232, 这款芯片使用的范围非常广, 并且年代久远. 但是这款芯片因为用的特别多, 所以中国就有很多厂家生产了仿造的P ...
- 使用elementUI滚动条之横向滚动
用过elementUI组件应该会知道它内置一个滚动效果,官网对此组件没有相关文档,也是细心网友发现的. <el-scrollbar></el-scrollbar> 将会出现滚动 ...
- MT【329】二次函数系数的最大最小
已知二次函数$f(x)=ax^2+bx+c$有零点,且$a+b+c=1$ 若$t=\min\{a,b,c\}$求$t$的最大值. 分析:由$a,c$的对称性,不妨$c\ge a$即$2a+b\le1$ ...
- Docke--基础篇
什么是Docker? Docker 最初是dotCloud公司创始人Solomon Hykes在法国期间发起的一个公司内部项目,它是基于dotCloud公司多年云服务技术的一次革新,并与2013年3月 ...
- JS学习笔记Day25
一.VSN 和 GitHub (一)VSN集中化的版本控制系统: 拥有一个单一的集中管理的服务器,保存所有文件的修订版本,而协同工作的人们都通过客户端连到这台服务器,取出最新的文件或者提交更新. (二 ...
- showdoc app接口文档编写利器
通过朋友介绍,才知道有这么好的一个在线接口编写文档开源项目,非常感谢原作者的贡献 ShowDoc介绍 关于ShowDoc的介绍,请访问:http://blog.star7th.com/2015/11/ ...
- eclipse Tomcat 容器已经启动 但右下角 progress 一直显示100%
今天在家里 遇到一个问题 先上图 我的默认超时时间 eclipse 默认的 45s 果然 到了时间 依旧是 显示超时 解决方法其实 很简单 我看到网上有人说是tomcat 或者 eclip ...