如果疯狂地弹进程,很容易导致内存爆炸,所以非常有必要设计一种功能,可以限定同时运行的进程数,这就是进程池。
举一个最简单的例子,
from multiprocessing import Pooldef test(N):print(N)if __name__ == '__main__':p = Pool(5)for i in range(10):p.apply_async(func=test, [i])p.close()
这里面p就是最多容量为5的一个进程池,apply_async表示将func压入进程池,当进程数达到5个时,发生阻塞,之后每完成一个进程,就添加一个进程,直到所有进程都已经装入进程池。
显而易见,线程池中最为关键的方法就是apply_async, 除了参数func代表将要执行的进程之外,还有其他可选参数,整体上apply_async的调用方法如下
apply_async(func, args, kwds, callback, error_callback)
其中,func不必多说,args为func的参数列表,对应上面案例中的[i],kwds为参数字典,对于形如下面的func而言,
def test(a, b):print(a+b)
args和kwds的区别如下
p.apply_async(func=test, args=[1,2])
p.apply_async(func=test, kwds={'a':1, 'b':2})
此外,callback表示,当进程执行完毕后的回调函数,error_callback表示当进程出现错误时的回调函数。
如想理解map_async,最好先复习一下Python中map的用法。map就是根据提供的函数对可迭代对象进行迭代操作,res = map(func, iters)就等价于res = [func(i) for i in iters]。
相应地,map_async的关键参数同样为func, iterable,其具体参数如下
map_async(func, iterable, chunksize, callback, error_callback)
其中,callback和error_callback和apply_async中的作用相同,都是迭代之后进行的回调操作。
chunksize为块尺寸,顾名思义,map_async会将可迭代参数分成多个区块,进行同时处理,理论上chunksize越大则处理越快。
close、terminate和join其中
close 阻止后续任务提交到进程池terminate 终止进程池join 等待进程池工作结束在实际应用中,terminate可以解决一个痛点问题,即进程池已经开始工作了,突然发现参数设置有误,想要马上停止进程池,这就是terminate大显身手的时候。
close和join一般配合使用,且join必须要在使用close或者terminate之后才能使用,表示等待进程池处理完成。