Python 多进程并发操作中进程池Pool的实例


Posted in Python onNovember 01, 2017

在利用Python进行系统管理的时候,特别是同时操作多个文件目录,或者远程控制多台主机,并行操作可以节约大量的时间。当被操作对象数目不大时,可以直接利用multiprocessing中的Process动态成生多个进程,10几个还好,但如果是上百个,上千个目标,手动的去限制进程数量却又太过繁琐,这时候进程池Pool发挥作用的时候就到了。

Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程来它。这里有一个简单的例子:

#!/usr/bin/env python
#coding=utf-8
"""
Author: Squall
Last modified: 2011-10-18 16:50
Filename: pool.py
Description: a simple sample for pool class
"""

from multiprocessing import Pool
from time import sleep

def f(x):
  for i in range(10):
    print '%s --- %s ' % (i, x)
    sleep(1)


def main():
  pool = Pool(processes=3)  # set the processes max number 3
  for i in range(11,20):
    result = pool.apply_async(f, (i,))
  pool.close()
  pool.join()
  if result.successful():
    print 'successful'


if __name__ == "__main__":
  main()

先创建容量为3的进程池,然后将f(i)依次传递给它,运行脚本后利用ps aux | grep pool.py查看进程情况,会发现最多只会有三个进程执行。pool.apply_async()用来向进程池提交目标请求,pool.join()是用来等待进程池中的worker进程执行完毕,防止主进程在worker进程结束前结束。但必pool.join()必须使用在pool.close()或者pool.terminate()之后。其中close()跟terminate()的区别在于close()会等待池中的worker进程执行结束再关闭pool,而terminate()则是直接关闭。result.successful()表示整个调用执行的状态,如果还有worker没有执行完,则会抛出AssertionError异常。

利用multiprocessing下的Pool可以很方便的同时自动处理几百或者上千个并行操作,脚本的复杂性也大大降低。

——————————————————————————————————

Python多进程并发(multiprocessing)

由于Python设计的限制(我说的是咱们常用的CPython)。最多只能用满1个CPU核心。

Python提供了非常好用的多进程包multiprocessing,你只需要定义一个函数,Python会替你完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。

1、新建单一进程

如果我们新建少量进程,可以如下:

import multiprocessing
import time

def func(msg):
for i in xrange(3):
print msg
time.sleep(1)

if __name__ == "__main__":
p = multiprocessing.Process(target=func, args=("hello", ))</ 
p.start()
p.join()
print "Sub-process done."

2、使用进程池

是的,你没有看错,不是线程池。它可以让你跑满多核CPU,而且使用方法非常简单。

注意要用apply_async,如果落下async,就变成阻塞版本了。

processes=4是最多并发进程数量。

import
multiprocessing
import
time
 
def
func(msg):
  for
i
in
xrange(3):
    print
msg
    time.sleep(1)
 
if
__name__
==
"__main__":
  pool
=
multiprocessing.Pool(processes=4)
  for
i
in
xrange(10):
    msg
=
"hello
 %d"
%(i)
    pool.apply_async(func,
(msg,
))
  pool.close()
  pool.join()
  print
"Sub-process(es)
 done."

3、使用Pool,并需要关注结果

更多的时候,我们不仅需要多进程执行,还需要关注每个进程的执行结果,如下:

import multiprocessing

import time



def func(msg):

for i in xrange(3):

print msg

time.sleep(1)

return "done " + msg



if __name__ == "__main__":

pool = multiprocessing.Pool(processes=4)

result = []

for i in xrange(10):

msg = "hello %d" %(i)

result.append(pool.apply_async(func, (msg, )))

pool.close()

pool.join()

for res in result:

print res.get()

print "Sub-process(es) done."

2014.12.25更新

根据网友评论中的反馈,在Windows下运行有可能崩溃(开启了一大堆新窗口、进程),可以通过如下调用来解决:

multiprocessing.freeze_support()

简易worker multiprocessing.Pool

多任务模型设计是一个比较复杂的逻辑,但是python对于多任务的处理却有种种方便的类库,不需要过多的纠结进程/线程间的操作细节。比如multiprocessing.Pool就是其中之一。

官方给的范例也很简单。

from multiprocessing import Pool

def f(x):
  return x*x

if __name__ == '__main__':
  pool = Pool(processes=4)       # start 4 worker processes
  result = pool.apply_async(f, [10])  # evaluate "f(10)" asynchronously
  print result.get(timeout=1)      # prints "100" unless your computer is *very* slow
  print pool.map(f, range(10))     # prints "[0, 1, 4,..., 81]"

并未做太多的详细解释。正好我手头有一段代码,需要请求几百个url,解析html页面获取一些信息,单线程for循环效率极低,因此看到了这个模块,想用这个实现多任务分析,参考代码如下:

from multiprocessing import Pool

def analyse_url(url):
  #do something with this url
  return analysis_result

if __name__ == '__main__':
  pool = Pool(processes=10)
  result = pool.map(analyse_url, url_list)

确实比以前单线程for循环url_list列表,一个个请求analyse_url要快得多,但是带来的问题就是一旦pool.map没执行完就ctrl-c中断程序,程序就会异常,永远无法退出,参考stackoverflow的这个帖子,修改为以下代码:

#result = pool.map(analyse_url, url_list)
result = pool.map_async(analyse_url, url_list).get(120)

至此问题完美解决。

以上这篇Python 多进程并发操作中进程池Pool的实例就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
Mar 06 Python
python类和函数中使用静态变量的方法
May 09 Python
Python文件夹与文件的相关操作(推荐)
Jul 25 Python
使用Python对Excel进行读写操作
Mar 30 Python
pandas对指定列进行填充的方法
Apr 11 Python
Python获取网段内ping通IP的方法
Jan 31 Python
Python从list类型、range()序列简单认识类(class)【可迭代】
May 31 Python
Python 中@property的用法详解
Jan 15 Python
python数据预处理 :数据抽样解析
Feb 24 Python
Pycharm 使用 Pipenv 新建的虚拟环境(图文详解)
Apr 16 Python
通过实例简单了解Python sys.argv[]使用方法
Aug 04 Python
Python使用eval函数执行动态标表达式过程详解
Oct 17 Python
python 3.0 模拟用户登录功能并实现三次错误锁定
Nov 01 #Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
Nov 01 #Python
Python编程实现双链表,栈,队列及二叉树的方法示例
Nov 01 #Python
Python栈算法的实现与简单应用示例
Nov 01 #Python
Python scikit-learn 做线性回归的示例代码
Nov 01 #Python
机器学习python实战之手写数字识别
Nov 01 #Python
Python定时器实例代码
Nov 01 #Python
You might like
Ajax PHP分页演示
2007/01/02 PHP
php提取字符串中网站url地址的方法
2014/12/03 PHP
php实现网站文件批量压缩下载功能
2015/10/28 PHP
Laravel实现搜索的时候分页并携带参数
2019/10/15 PHP
Extjs NumberField后面加单位实现思路
2013/07/30 Javascript
JqueryMobile动态生成listView并实现刷新的两种方法
2014/03/05 Javascript
node.js连接mongoDB数据库 快速搭建自己的web服务
2016/04/17 Javascript
iframe中使用jquery进行查找的方法【案例分析】
2016/06/17 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
2016/09/27 Javascript
javascript基础知识讲解
2017/01/11 Javascript
jQuery实现字体颜色渐变效果的方法
2017/03/29 jQuery
浅谈Vue SPA 首屏加载优化实践
2017/12/15 Javascript
简单的Vue SSR的示例代码
2018/01/12 Javascript
javascript深拷贝、浅拷贝和循环引用深入理解
2018/05/27 Javascript
Bootstrap模态对话框用法简单示例
2018/08/31 Javascript
element-ui组件table实现自定义筛选功能的示例代码
2019/03/15 Javascript
javascript设计模式 ? 桥接模式原理与应用实例分析
2020/04/13 Javascript
详解JSON.stringify()的5个秘密特性
2020/05/26 Javascript
[04:46]2018年度玩家喜爱的电竞媒体-完美盛典
2018/12/16 DOTA
python之Socket网络编程详解
2016/09/29 Python
python pygame实现方向键控制小球
2019/05/17 Python
如何在django中运行scrapy框架
2020/04/22 Python
HTML5 body设置自适应全屏
2020/05/07 HTML / CSS
Marriott中国:万豪国际酒店查询预订
2016/09/02 全球购物
德国狗狗用品在线商店:Schecker
2017/03/17 全球购物
eBay荷兰购物网站:eBay.nl
2020/06/26 全球购物
程序集与命名空间有什么不同
2014/07/25 面试题
软件测试笔试题
2012/10/25 面试题
会计专业自荐信范文
2013/12/02 职场文书
留学推荐信范文
2014/05/10 职场文书
企业法人代表授权委托书
2014/10/02 职场文书
2015年统计员个人工作总结
2015/07/23 职场文书
2016年寒假生活小结
2015/10/10 职场文书
60句有关成长的名言
2019/09/04 职场文书
解决thinkphp6(tp6)在状态码500下不报错,或者显示错误“Malformed UTF-8 characters”的问题
2021/04/01 PHP
使用Python获取字典键对应值的方法
2022/04/26 Python