我创建了一个命令行接口来运行用python(3.8(编写的模拟。我添加了一个选项,可以使用concurrent.futures,特别是ProcessPoolExecutor同时启动多个模拟。这是我第一次使用这个软件包,我遇到了一些问题。我创建的代码在windows 10和ubuntu 20.04(在wsl2上(中运行良好。但当我在ssh服务器(CentosOS 7(和ubuntu 18.04上启动它时失败了。我得到的例外是:BrokenProcessPool
。我还注意到一件事,当我启动代码时,要求减轻工作量,从而减少时间,这一切都很顺利。代码仅在繁重的工作负载下失败(例如,具有大量参数的模拟(。这表明存在某种超时时间。我已经尝试过使用不同的方法来创建进程:("fork"、"spawn"one_answers"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())
主.py
from .modes import Mode
def go():
mode = Mode(num_workers=5)
mode.run_p()
if __name__ == '__main__':
go()
简而言之,我的问题是:使用ProcessPoolExecutor,我需要做些什么才能让我的代码在centosOS7和windows中工作?欢迎提出任何建议!谢谢大家的帮助。
concurrent.futures.process.BrokenProcessPool: A process in the process pool was terminated abruptly while the future was running or pending.
由于服务器内存不足,进程很可能被OOM杀死:
BrokenProcessPool:
派生自BrokenExecutor(以前的RuntimeError(,此异常当ProcessPoolExecutor的一个工作程序具有以非干净的方式终止(例如,如果它被杀死从外部(。
您可以通过检查日志和dmesg
输出来确认这一点。
我也不建议手动更改max_workers
。默认值(os.cpu_count(((通常足够好,对于cpu绑定的工作负载,没有必要将其设置为大于可用cpu的数量,因为它实际上会由于上下文切换等原因而降低性能。