多处理池在嵌套函数中不起作用
multiprocessing pool not working in nested functions
以下代码未按预期执行。
import multiprocessing
lock = multiprocessing.Lock()
def dummy():
def log_results_l1(results):
lock.acquire()
print("Writing results", results)
lock.release()
def mp_execute_instance_l1(cmd):
print(cmd)
return cmd
cmds = [x for x in range(10)]
pool = multiprocessing.Pool(processes=8)
for c in cmds:
pool.apply_async(mp_execute_instance_l1, args=(c, ), callback=log_results_l1)
pool.close()
pool.join()
print("done")
dummy()
但如果函数没有嵌套,它确实有效。怎么回事。
multiprocessing.Pool
方法,如 apply*
和 *map*
方法必须同时 pickle 函数和参数。函数通过其限定名称进行腌制;本质上,在 unpickling 时,另一个进程需要能够导入它们在其中定义的模块并执行 getattr
调用以查找相关函数。嵌套函数在定义它们的函数之外按名称不可用,因此 pickling 失败。当您将函数移动到全局范围时,您修复了这个问题,这就是为什么它在您这样做时起作用的原因。
以下代码未按预期执行。
import multiprocessing
lock = multiprocessing.Lock()
def dummy():
def log_results_l1(results):
lock.acquire()
print("Writing results", results)
lock.release()
def mp_execute_instance_l1(cmd):
print(cmd)
return cmd
cmds = [x for x in range(10)]
pool = multiprocessing.Pool(processes=8)
for c in cmds:
pool.apply_async(mp_execute_instance_l1, args=(c, ), callback=log_results_l1)
pool.close()
pool.join()
print("done")
dummy()
但如果函数没有嵌套,它确实有效。怎么回事。
multiprocessing.Pool
方法,如 apply*
和 *map*
方法必须同时 pickle 函数和参数。函数通过其限定名称进行腌制;本质上,在 unpickling 时,另一个进程需要能够导入它们在其中定义的模块并执行 getattr
调用以查找相关函数。嵌套函数在定义它们的函数之外按名称不可用,因此 pickling 失败。当您将函数移动到全局范围时,您修复了这个问题,这就是为什么它在您这样做时起作用的原因。