多处理 AsyncResult.get() 在 Python 3.7.2 中挂起,但在 3.6 中不挂起

Multiprocessing AsyncResult.get() hangs in Python 3.7.2 but not in 3.6

我正在尝试将一些代码从 Python 3.6 移植到 Python 3.7 on Windows 10。我看到在调用 .get() 时多处理代码挂起AsyncResult 对象。有问题的代码要复杂得多,但我已将其归结为类似于以下程序的代码。

import multiprocessing


def main(num_jobs):
    num_processes = max(multiprocessing.cpu_count() - 1, 1)
    pool = multiprocessing.Pool(num_processes)

    func_args = []
    results = []

    try:
        for num in range(num_jobs):
            args = (1, 2, 3)
            func_args.append(args)
            results.append(pool.apply_async(print, args))

        for result, args in zip(results, func_args):
            print('waiting on', args)
            result.get()
    finally:
        pool.terminate()
        pool.join()


if __name__ == '__main__':
    main(5)

此代码也在 Python 2.7 中运行。由于某种原因,对 get() 的第一次调用在 3.7 中挂起,但在其他版本上一切正常。

我认为这是 Python 3.7.2 中的回归,如 here 所述。它似乎只影响 virtualenv 中 运行 时的用户。

目前,您可以按照 in this comment on the bug thread.

中描述的方法解决此问题
import _winapi
import multiprocessing.spawn
multiprocessing.spawn.set_executable(_winapi.GetModuleFileName(0))

这将强制子进程使用 real python.exe 而不是 virtualenv 中的子进程产生。因此,如果您使用 PyInstaller 将东西捆绑到一个 exe 文件中,这可能不合适,但是当从 CLI 使用本地 Python 安装 运行 时,它可以正常工作。