如何使用venv解决Python 3.7.2中的多处理停止工作问题

mei*_*812 9 python python-3.x

2019-01-12更新

我重新安装了python 3.7.1,并重新制作了venv,以恢复一切。

但是,我对3.7.2中发生的事情一无所知。


我在数据处理项目中一直使用multiprocessing.map_async和.apply_async。它在python 3.6到3.7.1之前都可以正常工作,但是当我升级到3.7.2并重新创建venv时,主进程无限期地挂起,子进程根本无法工作。

我正在使用Windows10和PyCharm社区。

我尝试了PyCharm中的工具和python -m venv来创建venv,但是都没有用。我在python.org中寻找文档,发现

https://docs.python.org/3.7/whatsnew/changelog.html#python-3-7-2-final

它说,

“ Windows上的venv现在将使用python.exe重定向器,而不是从基本环境中复制实际的二进制文件。”

我想知道这是否引起了问题。

示例代码如下:

from multiprocessing import freeze_support, Pool

def test_func(x):
    y = x + 1
    return y

if __name__ == '__main__':
freeze_support()
test_data = list(range(10))
with Pool(4) as test_pool:
    for test_datum in test_data:
        apply_result = test_pool.apply_async(test_func, test_datum)
        print(apply_result.get())
Run Code Online (Sandbox Code Playgroud)

我在最后一行添加一个断点,然后进入调试模式。然后,我发现apply_result对象(即multiprocessing.pool.ApplyResult)具有_cache属性。在_cache下,有一个相同的multiprocessing.pool.ApplyResult,但名称为“ 0(140716767896368) ”,它也具有_cache属性,并且一直打开。

调试

我感到绝望,并尝试了最简单的代码(从官方文档修改):

from multiprocessing import Pool, freeze_support

def f(x):
    return x*x

if __name__ == '__main__':
    freeze_support()
    p = Pool(5)
    print(p.map(f, [1, 2, 3]))
Run Code Online (Sandbox Code Playgroud)

它仍然挂着。

如果我选择系统解释器,而不使用venv,则可以正常工作。

[1, 4, 9]
Run Code Online (Sandbox Code Playgroud)

衷心感谢您为解决这个问题所提供的帮助。

小智 1

我在 Mac 和 VS Code 上遇到了同样的问题......

这是我的解决方案。

import joblib
from joblib import Parallel,delayed

def f(x):
    return x*x

number_of_cpu = joblib.cpu_count()
delayed_funcs = [delayed(f)(x) for x in [1,2,3]]
parallel_pool = Parallel(n_jobs=number_of_cpu,prefer="processes")
print(parallel_pool(delayed_funcs))
Run Code Online (Sandbox Code Playgroud)

无论如何,该文档都有详细记录......