python大法好

多进程 multiprocessing 之 Pool

2018-12-10  本文已影响0人  冬至是条狗

Pool 进程池

可以有效提升多进程的执行效率

  def func(args):
  print(args)

if __name__ == "__main__":
   p = multiprocessing.Pool(5)
   p.map(func, range(100))

map() 自带join功能,每次开启的进程数量最好不要大于CPU核数+1,第一个参数为要执行的函数,第二个参数要传递可迭代类型数据。如列表、元祖等,多个参数可以封装成字典、元祖、列表等嵌套进可迭代数据类型中:

def func(args):
    print(args)


if __name__ == "__main__":
   p = multiprocessing.Pool(5)
   p.map(func, [("haha", 1), "heihei"])

可以用一个进程池执行多个任务:

def func(args):
print(args)


def func2(args):
    print(args)


if __name__ == "__main__":
   p = multiprocessing.Pool(5)
   p.map(func, range(100))
   p.map(func2, ({"name": "haha"},))

该方法为同步开启进程,每次只执行一个,不能实现并发

def func(args):
    time.sleep(1)
    print(args)

if __name__ == "__main__":
    p = multiprocessing.Pool(5)
    for i in range(10):
        p.apply(func, args=(i, ))

可以实现并发,但使用时要注意join,不然主进程结束,子进程一并结束。

if __name__ == "__main__":
    p = multiprocessing.Pool(5)
    for i in range(10):
        p.apply_async(func, args=(i, ))
    p.close() # 需要先关闭,才能join
    p.join()

关于多进程的返回值问题,在普通的多进程中,无法取得函数返回值,只能通过队列、管道等方式进行多进程间的通信。而在进程池中可以获取返回值,其中apply方法直接return结果,而apply则返回进程的对象,可以通过 object.get()方式获取,但是会导致进程变成同步进程,解决方式为把执行结果添加到列表中,也就是将返回的对象先存储,最后再遍历列表通过对象的.get()方法获取结果。

在map()中返回值会在执行完毕后一次性存储在列表中返回。

import multiprocessing
import time
import os
def func(args):
      print("in func :", os.getpid())
      time.sleep(1)
      return args * args


def func2(nn):
      print(nn, "in func2 :", os.getpid())


if __name__ == "__main__":
     p = multiprocessing.Pool(5)
     for i in range(10):
         p.apply_async(func, args=(i, ), callback=func2) 
     p.close()
     p.join()

其中回调函数callback 为funk2,func2不能接收额外的传参,只能接收由func中返回的值,且,func函数由进程池管理,而回调函数由主进程执行。
耗时较长的任务开启多进程,而耗时较短的任务交给主进程,提高效率

上一篇 下一篇

猜你喜欢

热点阅读