前提,为何要用进程池POOL
当创建需要的子进程数量不多时,可以直接利用multiprocessing中的Process动态生成多个进程,但如果是上百甚至上千个目标,手动的去创建进程的工作量巨大,此时就可以用到multiprocessing模块提供的Pool方法。
初始化Pool时,可以指定一个最大进程数,当有新的请求提交到Pool时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到指定的最大值,那么该请求就会等待,知道池中有进程结束,才会用之前的进程来执行新的任务。
通过Process创建的进程,主进程会等子进程结束后,再结束,但是在进程池Pool中,进程池不会等,所以要通过以下代码po.join()(po = Pool(3))起到阻塞的作用,等待po中所有子进程执行完成后,主进程再向下代码走
知识点总结:
- po = Pool(3) 定义一个进程池,最大进程数3个
- Pool().apply_async(要调用的目标也就是函数名,(传递给目标的参数元祖也就是msg,)) : 进程池一次执行三个进程,如果满了,就等待其中一个执行结束后,等待中的下一个,填补进来
- po.join() 等待po中所有子进程执行完成,必须放在close语句之后
# -*- coding:utf-8 -*-
from multiprocessing import Pool
import os, time, random
def worker(msg):
t_start = time.time()
print("%s开始执行,进程号为%d" % (msg,os.getpid()))
# random.random()随机生成0~1之间的浮点数
time.sleep(random.random()*2)
t_stop = time.time()
print(msg,"执行完毕,耗时%0.2f" % (t_stop-t_start))
def main():
po = Pool(3) # 定义一个进程池,最大进程数3
for i in range(0, 10):
# Pool().apply_async(要调用的目标,(传递给目标的参数元祖,))
# 每次循环将会用空闲出来的子进程去调用目标
po.apply_async(worker, (i,))
print("----start----")
po.close() # 关闭进程池,关闭后po不再接收新的请求
po.join() # 等待po中所有子进程执行完成,必须放在close语句之后
print("-----end-----")
if __name__ == '__main__':
main()
#执行结果
----start----
0开始执行,进程号为13824
1开始执行,进程号为14632
2开始执行,进程号为14672
0 执行完毕,耗时1.11
3开始执行,进程号为13824
1 执行完毕,耗时1.07
4开始执行,进程号为14632
2 执行完毕,耗时1.33
5开始执行,进程号为14672
5 执行完毕,耗时0.20
6开始执行,进程号为14672
3 执行完毕,耗时0.65
7开始执行,进程号为13824
6 执行完毕,耗时0.18
8开始执行,进程号为14672
8 执行完毕,耗时0.13
9开始执行,进程号为14672
4 执行完毕,耗时1.66
9 执行完毕,耗时1.00
7 执行完毕,耗时1.65
-----end-----