所有示例的concurrent.futures代码都出现了“BrokenProcessPool”错误。

55

在我创建所需的实际应用程序之前,我正在努力对此有一个基本的理解。我最近从2.7转到了3.3。

直接从Python文档中复制粘贴的代码失败了,一个稍微简单的例子也是如此,来自这里

这是我的代码,源自第二个例子:

import concurrent.futures

nums = [1,2,3,4,5,6,7,8,9,10]

def f(x):
    return x * x

# Make sure the map and function are working
print([val for val in map(f, nums)])

# Test to make sure concurrent map is working
with concurrent.futures.ProcessPoolExecutor() as executor:
    for item in executor.map(f, nums):
        print(item)

这是输出结果:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
Traceback (most recent call last):
  File "<string>", line 420, in run_nodebug
  File "<module1>", line 13, in <module>
  File "C:\Python33\lib\concurrent\futures\_base.py", line 546, in result_iterator
    yield future.result()
  File "C:\Python33\lib\concurrent\futures\_base.py", line 399, in result
    return self.__get_result()
  File "C:\Python33\lib\concurrent\futures\_base.py", line 351, in __get_result
    raise self._exception
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

我该如何让这段代码按照预期工作?我希望这些示例可以直接使用。


也许这个解释会有帮助:https://dev59.com/87fna4cB1Zd3GeqPztOI#59320867 - Nairolf
2个回答

76

这是我的错,有两个原因:

  1. 代码没有保护,即没有if __name__
  2. 奇怪的Traceback是因为文件没有保存。以前从未给我带来问题,但在这种情况下却出了问题。

修复这两个问题后,错误得到解决。

最终测试代码:

import concurrent.futures

nums = [1,2,3,4,5,6,7,8,9,10]

def f(x):
    return x * x
def main():
    # Make sure the map and function are working
    print([val for val in map(f, nums)])

    # Test to make sure concurrent map is working
    with concurrent.futures.ProcessPoolExecutor() as executor:
        print([val for val in executor.map(f, nums)])

if __name__ == '__main__':
    main()

输出结果如预期:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

9
好奇怪,这只在我保存为.py文件后才可以运行。如果我尝试在iPython控制台或Jupyter Notebook中运行它,它就会失败。找得好! - David
27
在ProcessPoolExecutor的文档中现在提到,它不能在交互式控制台中运行。文档中指出:“__main__模块必须能够被工作进程导入。这意味着ProcessPoolExecutor无法在交互式解释器中运行。”请参考链接 - spirit
3
我的另一个发现是,当你在Windows中执行Process pools时,会出现该消息。在Linux下执行时,它可以正常运行。 - Mauricio Maroto
1
我正在Jupyter Lab(Windows)中完全按照所示运行此程序,但只看到第一行被打印,然后是“进程池中的一个进程在future运行或挂起时突然终止。”编辑:我似乎记得在Windows中必须使用ThreadProcessExecutor而不是ProcessThreadExecutor。更改调用后,它按预期运行。 - thistleknot
你最新的代码在我的情况下仍然出现了相同的错误:突然结束。 - MsTais
当我使用比计算机承载能力更多的进程来多进程运行我的算法时,我遇到了这个错误,导致内存溢出。我只是减少了工作进程的数量,问题就解决了。 - Karantai

40

在Windows系统下,使用ProcessPoolExecutor或其他生成新进程的并行代码时,保护主循环代码以避免递归生成子进程是非常重要的。

基本上,所有创建新进程的代码都必须位于if __name__ == '__main__':块内,原因与不能在解释器中执行该代码相同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接