【问题标题】:All example concurrent.futures code is failing with "BrokenProcessPool"所有示例 concurrent.futures 代码都因“BrokenProcessPool”而失败
【发布时间】:2013-03-31 18:57:54
【问题描述】:

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

this code from the python docs 的直接复制粘贴失败,here 中稍微简单的示例也是如此。

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

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.

如何让此代码按预期工作?我希望这些示例能够开箱即用。

【问题讨论】:

标签: python python-3.x


【解决方案1】:

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

  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]

【讨论】:

  • 这太奇怪了。它仅在保存的 .py 文件中对我有用。当我在 iPython 控制台或 Jupyter 笔记本中尝试它时,它失败了。很好的发现!
  • @David 现在在docs for ProcessPoolExecutor 中提到它在交互式控制台中不起作用。它说 main 模块必须可由工作子进程导入。这意味着 ProcessPoolExecutor 将无法在交互式解释器中工作。
  • 我的另一个发现是,当您尝试在 Windows 中执行进程池时会出现该消息。在 Linux 下执行时,运行良好。
  • 我正在完全按照 jupyter lab (windows) 中所示的方式运行它,我只看到打印的第一行后跟“进程池中的一个进程在未来正在运行或挂起时突然终止。 "编辑:我似乎记得在 Windows 中必须使用 ThreadProcessExecutor 而不是 ProcessThreadExecutor。交换调用时,它按预期运行。
【解决方案2】:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-05-18
    • 1970-01-01
    • 1970-01-01
    • 2019-01-09
    • 2018-09-05
    • 2015-11-19
    • 2020-05-02
    相关资源
    最近更新 更多