concurrent.futures 不适用于 ubuntu 18.04 和 centos 7

concurrent.futures does not work on ubuntu 18.04 and centosos 7

我为 运行 用 python (3.8) 编写的模拟创建了一个命令行界面。我添加了一个选项,可以使用 concurrent.futures 一次启动多个模拟,特别是 ProcessPoolExecutor.This 是我第一次使用这个包,我遇到了问题。我创建的代码在 windows 10 和 ubuntu 20.04(在 wsl2 上)中完美运行。但是当我在 ssh 服务器 (CentosOS 7) 和 ubuntu 18.04 上启动它时失败。 我得到的例外是:BrokenProcessPool。 我还注意到一件事,当我启动我的代码时要求减轻工作量并因此花费更少的时间,它完美地进行了。该代码仅在繁重的工作负载下失败(例如,具有大量参数的模拟)。这表明存在某种超时时间。我已经尝试过使用不同的方法创建进程:(“fork”、“spawn”和“forkserver”),总是出现同样的错误。异常与模拟代码无关,我已经进行了大量测试以确保情况并非如此。 下面是我的代码的一个最小示例(我无法粘贴由 6 个不同模块组成的整个模拟,因此为简单起见,模拟是“做某事”)。

modes.py

from concurrent.futures import ProcessPoolExecutor as Executor
from concurrent.futures import as_completed
import pickle
from model import Simulation


class Mode:
    def __init__(self, num_workers):
        self.num_workers = num_workers
        self.args = [{"key": "arg"} ,
                     {"key1": "arg"}]

    def simulate(self):
        result = Simulation() #do something
        with open("location", "wb") as file:
            pickle.dump(result, file)
        return "Saved"


    def run_p(self):
        with Executor(max_workers=self.num_workers) as executor:
            for out in as_completed([executor.submit(self.simulate, args) for args in self.args]):
                print(out.result())

main.py

from .modes import Mode

def go():
    mode = Mode(num_workers=5)
    mode.run_p()

if __name__ == '__main__':
    go()

简而言之,我的问题是:使用 ProcessPoolExecutor,我需要做什么才能让我的代码在 centosOS 7 和 windows 中工作?任何建议表示赞赏!谢谢大家的帮助。

concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.

由于服务器内存不足,进程很可能被 OOM 终止:

BrokenProcessPool:

Derived from BrokenExecutor (formerly RuntimeError), this exception class is raised when one of the workers of a ProcessPoolExecutor has terminated in a non-clean fashion (for example, if it was killed from the outside).

您可以通过检查日志和 dmesg 输出来确认这一点。

我也不建议手动更改 max_workers。默认值 (os.cpu_count()) 通常就足够了,对于 CPU 绑定工作负载,没有必要将其设置为大于可用 CPUs 的数字,因为它实际上会减慢由于上下文切换等引起的性能