使用python启动并行ssh呈现作业

2024-07-05 14:52:47 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在用Python编写一个脚本,用ssh在几台计算机(大约10台)上运行,然后让它们开始从Blender渲染3d图像。它工作得很好,除非下一台计算机的渲染在前一台计算机完成之前不会启动。有没有办法启动这些命令并让它们在自己的机器上同时运行?在

我的代码是什么样子的:

import os
path = /home/me
comp1 = ['sneffels','1','2'] #computer name, start frame, end frame
comp2 = ['bierstadt','3','4']
comp3 = ['diente','5','6']

os.system("ssh igp@" + str(comp1[0]) + " blender -b "+ str(path) +" -s " + str(comp1[1]) + " -e " + str(comp1[2]) + " -a")

os.system("ssh igp@" + str(comp2[0]) + " blender -b "+ str(path) +" -s " + str(comp2[1]) + " -e " + str(comp2[2]) + " -a")

os.system("ssh igp@" + str(comp3[0]) + " blender -b "+ str(path) +" -s " + str(comp3[1]) + " -e " + str(comp3[2]) + " -a")

Tags: path图像脚本os计算机systemframessh
3条回答

您可以尝试使用threading包。在Salty Crane的博客上可以找到一个简单的例子,可能会对你有所帮助。它应该允许您同时运行所有进程。在

您可能想thread您的电话。我准备了一个小示例,它只是回响一些东西(您可以将其更改为ssh)。我希望它足够清楚,这样你就能明白了

#!/usr/bin/env python

import threading
import os
import random

ips = ["192.168.1.25", "192.168.1.26", "192.168.1.27"]

def run(ip, otherParameter):
    os.system("echo %s with other parameter %s" % (ip, otherParameter))

if __name__ == "__main__":
    for ip in ips:
        thread = threading.Thread(target=run, args=[ip, random.randint(0, 10)])
        thread.run()

同时,代替操作系统,您应该看一下subprocess模块,或者更好的是,要想使用运行ssh命令的东西,请看一下paramiko模块。在

问题是os.system在程序完成之前不会返回,ssh直到您给它的命令完成后才会返回。在

这是不使用os.system-正如the documentation明确指出的那样:

The subprocess module provides more powerful facilities for spawning new processes and retrieving their results; using that module is preferable to using this function. See the Replacing Older Functions with the subprocess Module section in the subprocess documentation for some helpful recipes.

subprocess中,您可以创建一组子流程,然后在所有子流程启动后将它们全部合并。例如:

p1 = subprocess.Popen("ssh igp@" + str(comp1[0]) + " blender -b "+ str(path) +" -s " + str(comp1[1]) + " -e " + str(comp1[2]) + " -a", shell=True)
p2 = subprocess.Popen("ssh igp@" + str(comp2[0]) + " blender -b "+ str(path) +" -s " + str(comp2[1]) + " -e " + str(comp2[2]) + " -a", shell=True)
p3 = subprocess.Popen("ssh igp@" + str(comp3[0]) + " blender -b "+ str(path) +" -s " + str(comp3[1]) + " -e " + str(comp3[2]) + " -a", shell=True)
p1.wait()
p2.wait()
p3.wait()

这可能不是最好的办法。阅读子流程文档,了解为什么shell=True并传递字符串通常不如传递参数的list,以及管理子流程的其他方法等。。但同时,这可能是你已经拥有的最简单的改变。在

另一种选择是,首先不要对ssh命令执行shell操作,而是使用类似于^{}的方法从Python中生成远程进程。在

相关问题 更多 >