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多线程编程(八):使用Event实现线程间通信
Apr 05 Python
python类继承与子类实例初始化用法分析
Apr 17 Python
Python的消息队列包SnakeMQ使用初探
Jun 29 Python
详解python之多进程和进程池(Processing库)
Jun 09 Python
Python搭建FTP服务器的方法示例
Jan 19 Python
python实现比较文件内容异同
Jun 22 Python
Python中整数的缓存机制讲解
Feb 16 Python
Python换行与不换行的输出实例
Feb 19 Python
pandas DataFrame 数据选取,修改,切片的实现
Apr 24 Python
使用pymysql查询数据库,把结果保存为列表并获取指定元素下标实例
May 15 Python
浅谈keras 的抽象后端(from keras import backend as K)
Jun 16 Python
python使用numpy中的size()函数实例用法详解
Jan 29 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
Laravel中日期时间处理包Carbon的简单使用
2017/09/21 PHP
PHP实现通过strace定位故障原因的方法
2018/04/29 PHP
laravel 修改记住我功能的cookie保存时间的方法
2019/10/14 PHP
jquery实现瀑布流效果分享
2014/03/26 Javascript
javascript上下方向键控制表格行选中并高亮显示的方法
2015/02/13 Javascript
jquery插件orbit.js实现图片折叠轮换特效
2015/04/14 Javascript
jquery获取当前元素索引值用法实例
2015/06/10 Javascript
jQuery EasyUI中DataGird动态生成列的方法
2016/04/05 Javascript
javascript实现日期三级联动下拉框选择菜单
2020/12/03 Javascript
JS的Ajax与后端交互数据的实例
2018/08/08 Javascript
深入浅析angular和vue还有jquery的区别
2018/08/13 jQuery
nodejs更新package.json中的dependencies依赖到最新版本的方法
2018/10/10 NodeJs
jQuery Ajax async=&gt;false异步改为同步时,解决导致浏览器假死的问题
2019/07/22 jQuery
vue组件系列之TagsInput详解
2020/05/14 Javascript
聊聊vue 中的v-on参数问题
2021/01/29 Vue.js
[13:18]《一刀刀一天》之DOTA全时刻21:详解TI新赛制 A队再露獠牙
2014/06/24 DOTA
[04:20]DOTA2-DPC中国联赛 正赛 VG vs LBZS 选手采访 1月19日
2021/03/11 DOTA
详解Python编程中time模块的使用
2015/11/20 Python
详解python3百度指数抓取实例
2016/12/12 Python
详谈python read readline readlines的区别
2017/09/22 Python
python开发之anaconda以及win7下安装gensim的方法
2019/07/05 Python
python爬虫神器Pyppeteer入门及使用
2019/07/13 Python
Python Django Cookie 简单用法解析
2019/08/13 Python
python使用pip安装模块出现ReadTimeoutError: HTTPSConnectionPool的解决方法
2019/10/04 Python
解决pytorch DataLoader num_workers出现的问题
2020/01/14 Python
Python实现AES加密,解密的两种方法
2020/10/03 Python
利用Pycharm + Django搭建一个简单Python Web项目的步骤
2020/10/22 Python
Jupyter安装链接aconda实现过程图解
2020/11/02 Python
HTML5离线缓存Manifest是什么
2016/03/09 HTML / CSS
值得收藏的HTML5资源(学习html5的朋友可以收藏下)
2010/07/20 HTML / CSS
int *p=NULL和*p= NULL有什么区别
2014/10/23 面试题
大学生毕业自我鉴定范文
2013/11/03 职场文书
销售总监岗位职责
2014/01/04 职场文书
python爬虫selenium模块详解
2021/03/30 Python
OpenCV绘制圆端矩形的示例代码
2021/08/30 Python
教你使用Python获取QQ音乐某个歌手的歌单
2022/04/03 Python