进程池
进程池有什么用呢?我们先看个栗子:
from multiprocessing import Process,Pool import os import time def func(): time.sleep(2) print("the process Id is ",os.getpid()) if __name__ == '__main__': for i in range(10): p = Process(target=func) p.start()
启动十个子进程,等待2秒,然后打印pid,很简单的例子,这个跟pool有什么关系呢,python在启动子进程的时候,会把父进程的内存信息完全的clone一份,假如父进程的内存是1G,我要启动10个子进程,就需要11G的内存,如果启动100个进程,101G内存,这个不大现实,开销太大了。需要一个方法解决,使用进程池可以解决这个问题。
看看下面的例子:
from multiprocessing import Process,Pool import os import time def func(i): time.sleep(2) print("the process Id is ",os.getpid()) return i+100 def back(args): print("---process is done---",args) if __name__ == '__main__': pool = Pool(5) for i in range(10): pool.apply_async(func=func,args=(i,),callback=back) print("end") pool.close() pool.join()
这个例子中也是启动10个子进程,不过使用了进程池,进程池每次存入5个活动的子进程,等待这五个进程执行完,再放入5个进程。这样可以减少系统个的开销。
注意,pool.close()需要放在pool.join前面
进程池中可以放多个进程,这些进程可以并行,也可以串行。
pool.apply
pool.apply_async
上面的例子使用的是并行方式,使用的是pool.apply_async
下面的例子使用串行的方式:
from multiprocessing import Process,Pool import os import time def func(i): time.sleep(1) print("the process Id is ",os.getpid()) return i+100 def back(args): print("---process is done---",args) if __name__ == '__main__': pool = Pool(5) for i in range(10): pool.apply(func=func,args=(i,)) print("end") pool.close() pool.join()
pool.apply不能是使用“callbck=”参数。
还有一个问题需要说明一下,进程在调用callback参数的时候是通过主进程直接调用,而不是通过子进程调用的
from multiprocessing import Process,Pool import os import time def func(i): time.sleep(2) print("the process Id is ",os.getpid()) return i+100 def back(args): print("---process is done---",args,"调用callback的进程ID: ",os.getpid()) if __name__ == '__main__': pool = Pool(5) print("主进程ID:",os.getpid()) for i in range(10): pool.apply_async(func=func,args=(i,),callback=back) print("end") pool.close() pool.join()
输出结果:
D:\7_Python\Python37\python.exe D:/7_Python/S14/其他/aaaa.py 主进程ID: 9336 end the subprocess Id is 9636 ---process is done--- 100 调用callback的进程ID: 9336 the subprocess Id is 1520 ---process is done--- 101 调用callback的进程ID: 9336 the subprocess Id is the subprocess Id is 3380 9428 ---process is done--- 103 调用callback的进程ID: 9336 ---process is done--- 102 调用callback的进程ID: 9336 the subprocess Id is 1740 ---process is done--- 104 调用callback的进程ID: 9336 the subprocess Id is 9636 ---process is done--- 105 调用callback的进程ID: 9336 the subprocess Id is 1520 ---process is done--- 106 调用callback的进程ID: 9336 the subprocess Id is 9428 the subprocess Id is the subprocess Id is 3380 1740 ---process is done--- 108 调用callback的进程ID: 9336 ---process is done--- 107 调用callback的进程ID: 9336 ---process is done--- 109 调用callback的进程ID: 9336 Process finished with exit code 0
主进程ID是9336,调用callback函数的进程也是9336.