Pool 进程池
可以有效提升多进程的执行效率
- map()
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"},))
- appply() 同步开启进程池
该方法为同步开启进程,每次只执行一个,不能实现并发
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, ))
- apply_async ()
可以实现并发,但使用时要注意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()中返回值会在执行完毕后一次性存储在列表中返回。
- callback 回调函数
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函数由进程池管理,而回调函数由主进程执行。
耗时较长的任务开启多进程,而耗时较短的任务交给主进程,提高效率