Python多进程并发操作进程池Pool

摘要:
由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。

目录:

  1. multiprocessing模块
  2. Pool类
  3. apply
  4. apply_async
  5. map
  6. close
  7. terminate
  8. join
  9. 进程实例

multiprocessing模块

如果你打算编写多进程的服务程序,Unix/Linux无疑是正确的选择。由于Windows没有fork调用,难道在Windows上无法用Python编写多进程的程序?由于Python是跨平台的,自然也应该提供一个跨平台的多进程支持。multiprocessing模块就是跨平台版本的多进程模块。multiprocessing模块提供了一个Process类来代表一个进程对象,这个模块表示像线程一样管理进程,这个是multiprocessing的核心,它与threading很相似,对多核CPU的利用率会比threading好的多。

看一下Process类的构造方法:

__init__(self, group=None, target=None, name=None, args=(), kwargs={})

参数说明:
group:进程所属组。基本不用
target:表示调用对象。
args:表示调用对象的位置参数元组。
name:别名
kwargs:表示调用对象的字典。

下面看一个简单的例子

1 #coding=utf-8
2 importmultiprocessing
3 
4 defdo(n) :
5   #获取当前线程的名字
6   name =multiprocessing.current_process().name
7   print(name,'starting')
8   print("worker ", n)
9   return 
10 
11 if __name__ == '__main__':
12   numList =[]
13   for i in xrange(5) :
14     p = multiprocessing.Process(target=do, args=(i,))
15 numList.append(p)
16 p.start()
17 p.join()
18     print("Process end.")

运行结果

Process-1starting
worker  0
Process end.
Process-2starting
worker  1
Process end.
Process-3starting
worker  2
Process end.
Process-4starting
worker  3
Process end.
Process-5starting
worker  4
Process end.

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,并用其start()方法启动,这样创建进程比fork()还要简单。join()方法表示等待子进程结束以后再继续往下运行,通常用于进程间的同步。

注意:
在Windows上要想使用进程模块,就必须把有关进程的代码写在当前.py文件的if __name__ == ‘__main__’ :语句的下面,才能正常使用Windows下的进程模块。Unix/Linux下则不需要。

Pool类

Pool类可以提供指定数量的进程供用户调用,当有新的请求提交到Pool中时,如果池还没有满,就会创建一个新的进程来执行请求。如果池满,请求就会告知先等待,直到池中有进程结束,才会创建新的进程来执行这些请求。
下面介绍一下multiprocessing 模块下的Pool类下的几个方法:

1.apply()

函数原型:apply(func[, args=()[, kwds={}]])

该函数用于传递不定参数,同python中的apply函数一致,主进程会被阻塞直到函数执行结束(不建议使用,并且3.x以后不在出现)。

2.apply_async

函数原型:apply_async(func[, args=()[, kwds={}[, callback=None]]])

与apply用法一致,但它是非阻塞的且支持结果返回后进行回调。

3.map()

函数原型:map(func, iterable[, chunksize=None])

Pool类中的map方法,与内置的map函数用法行为基本一致,它会使进程阻塞直到结果返回。
注意:虽然第二个参数是一个迭代器,但在实际使用中,必须在整个队列都就绪后,程序才会运行子进程。

4.map_async()

函数原型:map_async(func, iterable[, chunksize[, callback]])
与map用法一致,但是它是非阻塞的。其有关事项见apply_async。

5.close()

关闭进程池(pool),使其不在接受新的任务。

6.terminal()

结束工作进程,不在处理未处理的任务。

7.join()

主进程阻塞等待子进程的退出, join方法要在close或terminate之后使用。

下面我们看一个简单的multiprocessing.Pool类的实例:

1 #-*- coding: utf-8 -*-
2 importtime
3 from multiprocessing importPool
4 defrun(fn):
5   #fn: 函数参数是数据列表的一个元素
6   time.sleep(1)
7   print(fn*fn)
8 
9 if __name__ == "__main__":
10   testFL = [1,2,3,4,5,6]
11   print ('shunxu:') #顺序执行(也就是串行执行,单进程)
12   s =time.time()
13   for fn intestFL:
14 run(fn)
15   t1 =time.time()
16   print ("顺序执行时间:", int(t1 -s))
17 
18   print ('concurrent:') #创建多个进程,并行执行
19   pool = Pool(10)  #创建拥有10个进程数量的进程池
20   #testFL:要处理的数据列表,run:处理testFL列表中数据的函数
21 pool.map(run, testFL)
22   pool.close()#关闭进程池,不再接受新的进程
23   pool.join()#主进程阻塞等待子进程的退出
24   t2 =time.time()
25   print ("并行执行时间:", int(t2-t1))

输出结果为:

shunxu:
1
4
9
16
25
36
顺序执行时间: 6
concurrent:
1
4
9
16
25
36
并行执行时间: 1

上例是一个创建多个进程并发处理与顺序执行处理同一数据,所用时间的差别。从结果可以看出,并发执行的时间明显比顺序执行要快很多,但是进程是要耗资源的,所以平时工作中,进程数也不能开太大。对Pool对象调用join()方法会等待所有子进程执行完毕,调用join()之前必须先调用close(),让其不再接受新的Process了。

更多有关进程介绍请参考官方文档:https://docs.python.org/2/library/multiprocessing.html

本文参考:http://blog.csdn.net/seetheworld518/article/details/49639651#t0

下次我们运用多进程爬取赶集网数据。

免责声明:文章转载自《Python多进程并发操作进程池Pool》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Wscript.Shell 对象详细介绍jenkins的安装下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Linux 利器- Python 脚本编程入门(一)

导读 众所周知,系统管理员需要精通一门脚本语言,而且招聘机构列出的职位需求上也会这么写。大多数人会认为 Bash (或者其他的 shell 语言)用起来很方便,但一些强大的语言(比如 Python)会给你带来一些其它的好处。 首先,我们会使用 Python 的命令行工具,还会接触到 Python 的面向对象特性(这篇文章的后半部分会谈到它)。 学习 P...

Python--命令行参数解析Demo

写没有操作界面的程序时,最讨厌的就是参数解析问题,尤其是很多参数那种,下面是一个小Demo,拿出来与各位分享: 1 # -*- coding:utf8 -*- 2 import os 3 import datetime 4 import sys 5 from optparse import OptionParser 6 7...

反编译python打包的exe文件

目录 1.前言 2.使用环境 3.还原过程 4.号外 5.exe文件和所用到的反编译工具  6.参考 7.去签名(补漏) 前言 拿到了利用驱动人生进行传播的病毒样本,发现是python打包成的exe文件,经过点波折才搞定。 使用环境 Python 3.6.1(网上说python2.7也可) 还原过程 首先用IDA进行分析,发现PyInstaller等关键信...

python——模块(Module)的概念、使用以及安装第三方模块

一、模块定义 python中,一个.py文件就是一个模块(Module)。使用模块的好处:1、提高了代码的可维护性。我们把函数进行分组,分别放在不同的模块中。2、编写代码不必要从0开始,当一个模块编写完毕,就可以被其他的模块引用。python有很多内置的模块和第三方模块供引用。3、可以避免函数名和变量名重复。相同的函数名和变量名可以同时存在于不同的模块中。...

python中多线程,多进程,多协程概念及编程上的应用

1, 多线程  线程是进程的一个实体,是CPU进行调度的最小单位,他是比进程更小能独立运行的基本单位。  线程基本不拥有系统资源,只占用一点运行中的资源(如程序计数器,一组寄存器和栈),但是它可以与同属于一个进程的其他线程共享全部的资源。  提高程序的运行速率,上下文切换快,开销比较少,但是不够稳定,容易丢失数据,形成死锁。 直接上代码: impor...

一个用python简单的封装了aria2的jsonrpc中adduri的脚本

aria2是一个十分牛逼的下载神器,有时候项目需要一个很牛逼的下载中间件的话,aria2是一个不错的选择。其中支持jsonrpc和websocket的特性尤其诱人。但是python用起来还是有点不爽,所以简单封装一下aria2的jsonrpc。 所以,用python简单的封装了aria2的jsonrpc中adduri的脚本。 使用起来非常简单,仅需要三行代...