最近在用multiprocessing.Pool的apply_async方法做多进程,在写示例的时候发现callback居然没有执行,遂记录原因如下。
目录
apply_async的func传入lambda:callback不执行
apply_async的callback为lambda:正常执行
apply_async的func传入lambda:callback不执行
正常能够执行的代码(示例改编自博主aaronthon):
进程池的回调函数callback - aaronthon - 博客园
def func1(n):
print(f'in func{n}')
def func2(ret):
# ret是func1的返回值,我们用不到
print(f'in callback func')
if __name__ == "__main__":
pool = Pool(5)
pool.apply_async(func1, args=(1,), callback=func2)
pool.close()
pool.join()
小啰嗦一下:注意args在单个参数情况下一定要带上逗号,就像(1,)这样。否则,python解释器不会将args当做元组(1,)传入,而是传入整数1,造成不必要的麻烦。
执行结果:
in func1
in callback func
如果用lambda取代func1,传入apply_async会怎样?
def func2(n):
print(f'in callback func{n}')
if __name__ == "__main__":
pool = Pool(5)
pool.apply_async(lambda x: print(f'in func{x}'), args=(1,), callback=func2)
pool.close()
pool.join()
执行结果:
没有任何输出。
这就说明了,apply_async在传入的func参数是lambda表达式时,回调函数是不会执行的(注意:是直接不执行了,而不是仅仅忽略了lambda表达式的返回值)。
我不清楚这是Python或者multiprocessing的feature还是bug,但是使用lambda作为func参数传入apply_async确实会导致回调函数完全被跳过而不被执行,需要警惕。
apply_async的callback为lambda:正常执行
前面已经说过,func不能为lambda。但是,callback函数本身为lambda的情况下,apply_async是可以正常执行callback函数的。实验如下:
def func1(n):
print(f'in func{n}')
def func2(ret):
print(f'in callback func')
if __name__ == "__main__":
pool = Pool(5)
pool.apply_async(func1, args=(1,), callback=lambda x:print('in callback func'))
pool.close()
pool.join()
执行结果:
in func1
in callback func
可见callback函数本身为lambda时callback执行不受影响,仅当func为lambda时callback不执行。