Python 多处理池映射异步的意外行为

Python 多处理池映射异步的意外行为,python,python-3.x,multiprocessing,python-multiprocessing,Python,Python 3.x,Multiprocessing,Python Multiprocessing,我有一些代码在Python3应用程序中对多个文件执行相同的操作,因此似乎是多处理的最佳候选。我试图使用池将工作分配给一些进程。在进行这些计算时,我希望代码继续执行其他操作(主要是为用户显示内容),因此我希望使用multiprocessing.Pool类的map\u async函数来执行此操作。我希望调用此函数后,代码将继续,结果将由我指定的回调处理,但这似乎没有发生。下面的代码显示了我尝试调用map\u async的三种方法以及我看到的结果: import multiprocessing NUM

我有一些代码在Python3应用程序中对多个文件执行相同的操作,因此似乎是
多处理
的最佳候选。我试图使用
将工作分配给一些进程。在进行这些计算时,我希望代码继续执行其他操作(主要是为用户显示内容),因此我希望使用
multiprocessing.Pool
类的
map\u async
函数来执行此操作。我希望调用此函数后,代码将继续,结果将由我指定的回调处理,但这似乎没有发生。下面的代码显示了我尝试调用
map\u async
的三种方法以及我看到的结果:

import multiprocessing
NUM_PROCS = 4
def func(arg_list):
    arg1 = arg_list[0]
    arg2 = arg_list[1]
    print('start func')
    print ('arg1 = {0}'.format(arg1))
    print ('arg2 = {0}'.format(arg2))
    time.sleep(1)
    result1 = arg1 * arg2
    print('end func')
    return result1

def callback(result):
    print('result is {0}'.format(result))


def error_handler(error1):
    print('error in call\n {0}'.format(error1))


def async1(arg_list1):
    # This is how my understanding of map_async suggests i should
    # call it. When I execute this, the target function func() is not called
    with multiprocessing.Pool(NUM_PROCS) as p1:
        r1 = p1.map_async(func,
                          arg_list1,
                          callback=callback,
                          error_callback=error_handler)


def async2(arg_list1):
    with multiprocessing.Pool(NUM_PROCS) as p1:
        # If I call the wait function on the result for a small
        # amount of time, then the target function func() is called
        # and executes sucessfully in 2 processes, but the callback
        # function is never called so the results are not processed
        r1 = p1.map_async(func,
                          arg_list1,
                          callback=callback,
                          error_callback=error_handler)
        r1.wait(0.1)


def async3(arg_list1):
    # if I explicitly call join on the pool, then the target function func()
    # successfully executes in 2 processes and the callback function is also
    # called, but by calling join the processing is not asynchronous any more
    # as join blocks the main process until the other processes are finished.
    with multiprocessing.Pool(NUM_PROCS) as p1:
        r1 = p1.map_async(func,
                          arg_list1,
                          callback=callback,
                          error_callback=error_handler)
        p1.close()
        p1.join()


def main():
    arg_list1 = [(5, 3), (7, 4), (-8, 10), (4, 12)]
    async3(arg_list1)

    print('pool executed successfully')


if __name__ == '__main__':
    main()

在main中调用
async1
async2
async3
时,每个函数的注释中都会描述结果。有人能解释一下为什么不同的电话是这样的吗?最后,我想调用
map\u async
,就像在
async1
中那样,这样我就可以在工作进程繁忙时在主进程中执行其他操作。我用Python2.7和3.6在较旧的RH6 linux机器和较新的ubuntu虚拟机上测试了这段代码,得到了相同的结果。

这是因为当您使用
多处理.Pool
作为上下文管理器时,它会立即退出所有工作程序,而不必等待正在进行的任务完成

3.3版新增:
Pool
对象现在支持上下文管理协议–请参阅上下文管理器
类型__输入
返回池对象,然后调用终止()


IMO使用
terminate()
作为上下文管理器的
\uuuuuuuuuuuuuuuuuuuuuuuuuuu
方法并不是一个很好的设计选择,因为大多数人直觉上都希望调用
close()
,这将等待正在进行的任务在退出之前完成。不幸的是,您所能做的就是重构代码,避免使用上下文管理器,或者重构代码,以确保在
完成其工作之前不会将
块分开。

感谢您的解释,我当然不希望池在所有进程上调用terminate。在我的玩具示例中,我应该意识到的另一件事是,如果代码到达主进程的末尾并退出,子进程就会死亡。所以我需要保持循环,等待我的玩具示例中的过程正常工作。我还需要保留对池的引用以保持进程的活动,否则池将被垃圾收集,进程将被杀死。这两个问题都由主GUI进程在实际应用程序中解决,因此一切都保持活跃。