Python多进程+子进程问题

4
我有一个二进制文件(比如说 a.out),我想用不同的配置来调用它。我想在一个拥有40个核心的机器上并行运行这些配置。下面是我的代码草图。
这非常简单:我生成一个配置并将其传递给工作进程,工作进程使用 subprocess 调用带有该配置的二进制文件。我还将输出重定向到文件。我们称这段代码为 run.py
def worker(cmdlist, filename):
    outputfile = open(filename, 'wb')
    // here it essentially executes  a.out config > outputfile
    subprocess.call(cmdlist, stderr=outputfile, stdout=outputfile) 
    outputfile.close()

def main():
    pool = Pool(processes = 40)
    for config in all_configs
        filename, cmdlist = genCmd(config)
        res = pool.apply_async(worker, [cmdlist, filename])
        results.append(res)
    for res in results:
        res.get()
    pool.close()

但是在我启动程序之后,我发现生成的进程数量未达预期。我明确提交了超过40个worker,但在top命令中,我只看到了大约20个a.out。我看到很多run.py处于“睡眠”状态(即在top命令中为“S”)。当我使用 ps auf 命令时,我还看到许多处于“S+”状态的run.py,没有二进制文件被生成出来。只有一半左右生成了“a.out”。
我在想,这是为什么?我将输出重定向到网络挂载的硬盘上,这可能是一个原因,但在top命令中,我只看到10%wa(我理解为等待IO的时间占总时间的10%)。我认为这不会导致CPU闲置50%。此外,我应该至少可以生成二进制文件,而不是被困在 run.py 中。我的二进制文件运行时间也足够长。我应该真的能看到40个作业长时间运行。
是否还有其他解释?或者我在python代码中有错吗?

1
你在 all_configs 中有多少个配置? - JoshRagem
@JoshRagem,比40多得多,就像我在原始问题中所说的那样。 - CuriousMind
尝试在a.out中增加明显的延迟。 - alexander
如果你让它运行到结束,输出是否显示所有任务的证据?你是否检查过确保如果你没有看到任务就不会运行它们? - JoshRagem
1
对于类似的任务,我喜欢使用类似 xargs -n 1 -P 40 a.out <parameters_file 的东西来保持40个a.out进程运行,每个进程都有一个参数,这些参数来自可能包含数千个参数的parameters_file。如果需要基于参数构建复杂的命令行,则可能需要用小脚本替换a.out。 - Brian Swift
如果您有最终所做的最小工作示例,我们将不胜感激。您最终是否像@JT建议的那样根本没有使用Pool呢? - Steve Heim
1个回答

1
我曾经使用的一种方法是同时在多个核心上运行许多并发进程,这是通过使用 p = subprocess.Popen(...) 和 p.Poll() 实现的。在你的情况下,我认为你可以完全跳过使用 Pool。我本来可以给你一个更好的例子,但不幸的是我无法再访问那段代码了。

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