Python多进程库multiprocessing中进程池Pool类的使用
问题起因
最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果。没错!类似bagging ensemble!只是我没有抽样。文本不大,大概3000行,topic个数为8,于是我写了一个串行的程序,一个topic算完之后再算另一个topic。可是我在每个topic中用了GridSearchCV
来调参,又要选特征又要调整regressor的参数,导致参数组合一共有1782种。我真是低估了调参的时间,程序跑了一天一夜最后因为忘记import一个库导致最终的预测精度没有算出来。后来想到,既然每个topic的预测都是独立的,那是不是可以并行呢?
Python中的多线程与多进程
但是听闻Python的多线程实际上并不能真正利用多核,所以如果使用多线程实际上还是在一个核上做并发处理。不过,如果使用多进程就可以真正利用多核,因为各进程之间是相互独立的,不共享资源,可以在不同的核上执行不同的进程,达到并行的效果。同时在我的问题中,各topic相互独立,不涉及进程间的通信,只需最后汇总结果,因此使用多进程是个不错的选择。
multiprocessing
一个子进程
multiprocessing模块提供process类实现新建进程。下述代码是新建一个子进程。
- from multiprocessing import Process
- def f(name):
- print 'hello', name
- if __name__ == '__main__':
- p = Process(target=f, args=('bob',)) # 新建一个子进程p,目标函数是f,args是函数f的参数列表
- p.start() # 开始执行进程
- p.join() # 等待子进程结束
上述代码中p.join()
的意思是等待子进程结束后才执行后续的操作,一般用于进程间通信。例如有一个读进程pw和一个写进程pr,在调用pw之前需要先写pr.join()
,表示等待写进程结束之后才开始执行读进程。
多个子进程
如果要同时创建多个子进程可以使用multiprocessing.Pool
类。该类可以创建一个进程池,然后在多个核上执行这些进程。
- import multiprocessing
- import time
- def func(msg):
- print multiprocessing.current_process().name + '-' + msg
- if __name__ == "__main__":
- pool = multiprocessing.Pool(processes=4) # 创建4个进程
- for i in xrange(10):
- msg = "hello %d" %(i)
- pool.apply_async(func, (msg, ))
- pool.close() # 关闭进程池,表示不能在往进程池中添加进程
- pool.join() # 等待进程池中的所有进程执行完毕,必须在close()之后调用
- print "Sub-process(es) done."
输出结果如下:
- Sub-process(es) done.
- PoolWorker-34-hello 1
- PoolWorker-33-hello 0
- PoolWorker-35-hello 2
- PoolWorker-36-hello 3
- PoolWorker-34-hello 7
- PoolWorker-33-hello 4
- PoolWorker-35-hello 5
- PoolWorker-36-hello 6
- PoolWorker-33-hello 8
- PoolWorker-36-hello 9
上述代码中的pool.apply_async()
是apply()
函数的变体,apply_async()
是apply()
的并行版本,apply()
是apply_async()
的阻塞版本,使用apply()
主进程会被阻塞直到函数执行结束,所以说是阻塞版本。apply()
既是Pool
的方法,也是Python内置的函数,两者等价。可以看到输出结果并不是按照代码for循环中的顺序输出的。
多个子进程并返回值
apply_async()
本身就可以返回被进程调用的函数的返回值。上一个创建多个子进程的代码中,如果在函数func
中返回一个值,那么pool.apply_async(func, (msg, ))
的结果就是返回pool中所有进程的值的对象(注意是对象,不是值本身)。
- import multiprocessing
- import time
- def func(msg):
- return multiprocessing.current_process().name + '-' + msg
- if __name__ == "__main__":
- pool = multiprocessing.Pool(processes=4) # 创建4个进程
- results = []
- for i in xrange(10):
- msg = "hello %d" %(i)
- results.append(pool.apply_async(func, (msg, )))
- pool.close() # 关闭进程池,表示不能再往进程池中添加进程,需要在join之前调用
- pool.join() # 等待进程池中的所有进程执行完毕
- print ("Sub-process(es) done.")
- for res in results:
- print (res.get())
上述代码输出结果如下:
- Sub-process(es) done.
- PoolWorker-37-hello 0
- PoolWorker-38-hello 1
- PoolWorker-39-hello 2
- PoolWorker-40-hello 3
- PoolWorker-37-hello 4
- PoolWorker-38-hello 5
- PoolWorker-39-hello 6
- PoolWorker-37-hello 7
- PoolWorker-40-hello 8
- PoolWorker-38-hello 9
与之前的输出不同,这次的输出是有序的。
如果电脑是八核,建立8个进程,在Ubuntu下输入top命令再按下大键盘的1,可以看到每个CPU的使用率是比较平均的,如下图:
在system monitor中也可以清楚看到执行多进程前后CPU使用率曲线的差异。
Python多进程库multiprocessing中进程池Pool类的使用的更多相关文章
- Python多进程库multiprocessing中进程池Pool类的使用[转]
from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...
- Python多进程库multiprocessing创建进程以及进程池Pool类的使用
问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似bag ...
- PYTHON多进程编码结束之进程池POOL
结束昨晚开始的测试. 最后一个POOL. A,使用POOL的返回结果 #coding: utf-8 import multiprocessing import time def func(msg): ...
- multiprocessing中进程池,线程池的使用
multiprocessing 多进程基本使用 示例代码1 import time import random from multiprocessing import Process def run( ...
- python学习笔记——multiprocessing 多进程组件 进程池Pool
1 进程池Pool基本概述 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量时间,如果操作的对象数目不大时,还可以直接适用Process类动态生成 ...
- python 进程池pool简单使用
平常会经常用到多进程,可以用进程池pool来进行自动控制进程,下面介绍一下pool的简单使用. 需要主动是,在Windows上要想使用进程模块,就必须把有关进程的代码写if __name__ == ‘ ...
- Python多进程并发操作进程池Pool
目录: multiprocessing模块 Pool类 apply apply_async map close terminate join 进程实例 multiprocessing模块 如果你打算编 ...
- [转]Python多进程并发操作中进程池Pool的应用
Pool类 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量的时间.如果操作的对象数目不大时,还可以直接使用Process类动态的生成多个进程,十 ...
- Python多进程并发操作中进程池Pool的应用
Pool类 在使用Python进行系统管理时,特别是同时操作多个文件目录或者远程控制多台主机,并行操作可以节约大量的时间.如果操作的对象数目不大时,还可以直接使用Process类动态的生成多个进程,十 ...
随机推荐
- [剑指Offer]38-字符串的全排列
链接 https://www.nowcoder.com/practice/fe6b651b66ae47d7acce78ffdd9a96c7?tpId=13&tqId=11180&tPa ...
- [SpringBoot]Web综合开发-笔记
Web开发 Json接口开发 @RestController 给类添加 @RestController 即可,默认类中的方法都会以 json 的格式返回. 自定义filter filter作用: 用于 ...
- 粒子动画——Pygame
你是否也想做出下图这么漂亮的动态效果?想的话就跟着我一起做吧=.= 工具: Python--Pygame 仔细观察上图,你能发现哪些机制呢?再在下面对比一下是否跟你想的一样. 运行机制: 1.随机方向 ...
- day3-selenium的使用及
如果是python2的情况下需要设置: # _*_ coding:utf-8 _*_,这样的编码来保证输入中文在运行时不会报错,另外在中文的前边加上u保证编译时不会报错 from selenium i ...
- 关于loadtxt编码问题的解决方法
I am trying to load data with numpy.loadtxt... The file im trying to read is using cp1252 coding. Is ...
- Java集合:ConcurrentHashMap原理分析
集合是编程中最常用的数据结构.而谈到并发,几乎总是离不开集合这类高级数据结构的支持.比如两个线程需要同时访问一个中间临界区(Queue),比如常会用缓存作为外部文件的副本(HashMap).这篇文章主 ...
- xpath获取一个标签下的多个同级标签
一.问题: 我在使用xpath获取文章内容的时候会遇到,多个相同的标签在同一级下面,但是我们只需要获取一部分的内容.比如我不想需要原标题这些内容. 二.解决: Xpath中有一个position()的 ...
- jxl操作excel写入数据不覆盖原有数据示例
public void readTO() { Workbook wb = null; WritableWorkbook wwb = null; try { ...
- J2CACHE 两级缓存框架
概述 缓存框架我们有ehcache 和 redis 分别是 本地内存缓存和 分布式缓存框架.在实际情况下如果单台机器 使用ehcache 就可以满足需求了,速度快效率高,有些数据如果需要多台机器共享这 ...
- SQL Server CTE 递归查询全解 -- 转 学习
在TSQL脚本中,也能实现递归查询,SQL Server提供CTE(Common Table Expression),只需要编写少量的代码,就能实现递归查询,本文详细介绍CTE递归调用的特性和使用示例 ...