我希望能够运行一个脚本(例如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脚本没有意义,请告诉我什么是更好的选择;我以前从未做过,也不知道我在做什么。
答案 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()
现在,因为我们在完成所有并行处理之后打印输出 ,所以不会混淆。