Python进程池apply_async的callback函数不执行的解决方案

最近在用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不执行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
`apply_async`函数的`error_callback`参数是一个可选的回调函数,它会在任务执行过程中出现异常时被调用。 当一个任务在进程执行时,如果该任务出现了异常,那么`apply_async`函数会将该异常传递给`error_callback`函数进行处理。`error_callback`函数会接收到一个异常对象作为参数,你可以在该函数中对异常进行处理或记录。如果`error_callback`函数没有被指定,那么在任务执行过程中出现异常时,该异常会被忽略,不会被捕获和处理。 下面是一个例子,演示如何在`apply_async`函数中使用`error_callback`参数: ```python import multiprocessing def func(x): # 模拟一个出现异常的任务 return 1 / x def handle_error(exc): print(f"Error occurred: {exc}") if __name__ == "__main__": pool = multiprocessing.Pool(processes=2) result = pool.apply_async(func, args=(0,), error_callback=handle_error) pool.close() pool.join() ``` 在这个例子中,我们定义了一个`func`函数,它会接收一个参数 `x`,并尝试对`x`进行除法运算。当`x`等于0时,该函数会出现异常。我们使用`apply_async`函数提交了一个参数为0的任务,同时指定了`handle_error`函数作为`error_callback`参数。在`handle_error`函数中,我们只是简单地打印出了异常信息。在这个例子中,我们通过指定`error_callback`参数来处理任务执行过程中出现的异常。 需要注意的是,`error_callback`函数只会在任务执行过程中出现异常时被调用,如果任务顺利执行完毕,则不会调用`error_callback`函数
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值