脚本与参数并行运行程序的多个实例

时间:2018-11-05 00:01:55

标签: automation

我希望能够运行一个脚本(例如python脚本或对这些事情最有意义的脚本),该脚本的作用等同于以下内容:

$ program -i input -k 0.1 -m 0.01 &
$ program -i input -k 0.2 -m 0.22 &
$ program -i input -k 0.3 -m 3.03 &

我想在脚本中设置我想要的任何参数,然后键入“ python script.py”,让它运行我想要的程序的许多实例,所有这些实例都在后台并行进行。我见过有人推荐subprocess.Popen(),但我不知道如何设置它以并行运行多个作业。我该怎么做?

我曾经考虑列出命令并对其进行遍历,但是1)我认为它将在队列中运行第二个任务之前等待第一个任务完成,并且2)效率低下。

此外,如果将其编写为python脚本没有意义,请告诉我什么是更好的选择;我以前从未做过,也不知道我在做什么。

1 个答案:

答案 0 :(得分:1)

使用multiprocessing模块的简单Python解决方案如下所示:

import os
import multiprocessing

def run_command(cmd):
    """ execute cmd via the shell. """
    print("starting `{}` ...".format(cmd))
    os.system(cmd)
    print("end `{}`".format(cmd))

def run_commands(commands, n_parallel):
    """ run commands (up to n_parallel in parallel). """
    worker = multiprocessing.Pool(n_parallel)
    worker.map(run_command, commands)

if __name__ == "__main__":
    run_commands([
        "program -i input -k 0.1 -m 0.01",
        "program -i input -k 0.2 -m 0.22",
        "program -i input -k 0.3 -m 3.03",
    ], n_parallel=2)

重点是map()的{​​{1}}方法。此函数获取一个输入值列表(在我们的示例中为shell命令),并将它们输入到另一个函数中,每个函数都在其自己的进程中,以并行方式达到最大的进程池大小。

但是,这个简单的脚本有一个缺点:并行运行的shell命令的输出将全部混合在一起。可以通过捕获并返回multiprocessing.Pool中的命令输出来避免这种情况,例如通过使用run_command()而不是subprocess.check_output()

os.system()

import subprocess def run_command(cmd): try: output = subprocess.check_output(cmd, shell=True) except subprocess.CalledProcessError: output = "ERROR in {}".format(cmd) return output 将收集并以列表的形式返回这些输出,我们可以将其与命令重新组合,以便multiprocessing.Pool.map()返回(命令,输出)对的列表:

run_commands()

现在,因为我们在完成所有并行处理之后打印输出 ,所以不会混淆。