zoukankan      html  css  js  c++  java
  • Python-Pool类

    目录:

    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 import multiprocessing
     3 
     4 def do(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-1 starting
    worker  0
    Process end.
    Process-2 starting
    worker  1
    Process end.
    Process-3 starting
    worker  2
    Process end.
    Process-4 starting
    worker  3
    Process end.
    Process-5 starting
    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 import time
     3 from multiprocessing import Pool
     4 def run(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 in testFL:
    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

  • 相关阅读:
    java基础之分辨final,static, abstract
    HTML DOM
    Zero Copy-转载201604
    Zero Copy
    java 虚拟机
    Spring Junit4
    【转】Java的序列化和反序列化总结
    【转】SQL Server 查询处理中的各个阶段(SQL执行顺序)
    【转】linux sar命令详解
    【转】linux top命令详解
  • 原文地址:https://www.cnblogs.com/jinan1/p/10614504.html
Copyright © 2011-2022 走看看