如果疯狂地弹进程,很容易导致内存爆炸,所以非常有必要设计一种功能,可以限定同时运行的进程数,这就是进程池。
举一个最简单的例子,
from multiprocessing import Pool
def 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
越大则处理越快。
其中
在实际应用中,terminate
可以解决一个痛点问题,即进程池已经开始工作了,突然发现参数设置有误,想要马上停止进程池,这就是terminate
大显身手的时候。
close
和join
一般配合使用,且join
必须要在使用close
或者terminate
之后才能使用,表示等待进程池处理完成。