Python多进程库multiprocessing中进程池Pool类的使用详解


Posted in Python onNovember 24, 2017

问题起因

最近要将一个文本分割成好几个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的使用率是比较平均的,如下图:

Python多进程库multiprocessing中进程池Pool类的使用详解

在system monitor中也可以清楚看到执行多进程前后CPU使用率曲线的差异。

Python多进程库multiprocessing中进程池Pool类的使用详解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中用Ctrl+C终止多线程程序的问题解决
Mar 30 Python
python计算圆周长、面积、球体体积并画出圆
Apr 08 Python
Python函数式编程指南(二):从函数开始
Jun 24 Python
Python 通过调用接口获取公交信息的实例
Dec 17 Python
Python给定一个句子倒序输出单词以及字母的方法
Dec 20 Python
Python实现多进程的四种方式
Feb 22 Python
Django后端接收嵌套Json数据及解析详解
Jul 17 Python
python3 map函数和filter函数详解
Aug 26 Python
python 使用事件对象asyncio.Event来同步协程的操作
May 04 Python
Ubuntu 20.04安装Pycharm2020.2及锁定到任务栏的问题(小白级操作)
Oct 29 Python
Python中用xlwt制作表格实例讲解
Nov 05 Python
关于Python3的import问题(pycharm可以运行命令行import错误)
Nov 18 Python
pip安装Python库时遇到的问题及解决方法
Nov 23 #Python
python清理子进程机制剖析
Nov 23 #Python
Python3 加密(hashlib和hmac)模块的实现
Nov 23 #Python
Python2.7基于笛卡尔积算法实现N个数组的排列组合运算示例
Nov 23 #Python
深入理解Python3 内置函数大全
Nov 23 #Python
Python内置函数delattr的具体用法
Nov 23 #Python
Python 内置函数memoryview(obj)的具体用法
Nov 23 #Python
You might like
php+mysql分页代码详解
2008/03/27 PHP
PHP简单留言本功能实现代码
2017/06/09 PHP
Symfony2针对输入时间进行查询的方法分析
2017/06/28 PHP
JS去除字符串两端空格的简单实例
2013/12/27 Javascript
jQuery Html控件基本操作(日常收集整理)
2016/03/11 Javascript
详解bootstrap的modal-remote两种加载方式【强化】
2017/01/27 Javascript
微信小程序 后台登录(非微信账号)实例详解
2017/03/31 Javascript
Webpack性能优化 DLL 用法详解
2017/08/10 Javascript
微信小程序实现打开内置地图功能【附源码下载】
2017/12/07 Javascript
详解使用jest对vue项目进行单元测试
2018/09/07 Javascript
微信小程序人脸识别功能代码实例
2019/05/07 Javascript
layer实现登录弹框,登录成功后关闭弹框并调用父窗口的例子
2019/09/11 Javascript
[03:42]2014DOTA2西雅图国际邀请赛 Navi战队巡礼
2014/07/07 DOTA
详解Python中的__init__和__new__
2014/03/12 Python
python实现绘制树枝简单示例
2014/07/24 Python
Python实现曲线点抽稀算法的示例
2017/10/12 Python
Python解决N阶台阶走法问题的方法分析
2017/12/28 Python
详解爬虫被封的问题
2019/04/23 Python
python 随机生成10位数密码的实现代码
2019/06/27 Python
将python安装信息加入注册表的示例
2019/11/20 Python
Python3 main函数使用sys.argv传入多个参数的实现
2019/12/25 Python
Python读取表格类型文件代码实例
2020/02/17 Python
解决pytorch多GPU训练保存的模型,在单GPU环境下加载出错问题
2020/06/23 Python
Python3中FuzzyWuzzy库实例用法
2020/11/18 Python
python gui开发——制作抖音无水印视频下载工具(附源码)
2021/02/07 Python
Html5 Geolocation获取地理位置信息实例
2016/12/09 HTML / CSS
携程旅行网:中国领先的在线旅行服务公司
2017/02/17 全球购物
Java语言的优势
2015/01/10 面试题
英语系毕业生自荐信
2013/10/31 职场文书
婚礼主持词开场白
2014/03/13 职场文书
劳资员岗位职责
2015/02/13 职场文书
手机销售员岗位职责
2015/04/11 职场文书
身份证丢失证明
2015/06/19 职场文书
会议室使用管理制度
2015/08/06 职场文书
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
2021/05/28 Python
分析MySQL优化 index merge 后引起的死锁
2022/04/19 MySQL