2

私はPythonでスクリプトを作成して、数台のコンピューター(約10台)にSSHで接続し、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")
4

6 に答える 6

2

問題はos.system、プログラムが完了するまで戻らずssh、指定したコマンドが完了するまで戻らないことです。

これは、使用しない多くの理由の1つですos.systemドキュメントに明示的に記載されているように:

サブプロセスモジュールは、新しいプロセスを生成してその結果を取得するためのより強力な機能を提供します。この関数を使用するよりも、そのモジュールを使用することをお勧めします。いくつかの役立つレシピについては、サブプロセスのドキュメントの「古い関数をサブプロセスモジュールに置き換える」セクションを参照してください。

では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、パラメータの受け渡し、サブプロセスを管理する他の方法などほど良くありません。しかし、その間、これはおそらくあなたがすでに持っているものからの最も簡単な変更です。

もう1つの方法はssh、最初からコマンドを実行せずにparamiko、Python内からリモートプロセスを生成するようなものを使用することです。

于 2013-02-05T21:58:53.600 に答える
0

スレッドパッケージを使用してみることができます。あなたを助けるかもしれない簡単な例はここSaltyCraneブログで見つけることができます。これにより、すべてのプロセスを同時に実行できるようになります。

于 2013-02-05T21:52:47.457 に答える
0

通話をスレッド化することをお勧めします。何かをエコーするだけの小さな例を用意しました(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()

また、os.systemの代わりに、サブプロセスモジュールを確認する必要があります。さらに、sshコマンドの実行を目的としたものを使用するには、paramikoモジュールを確認する必要があります。

于 2013-02-05T21:59:10.717 に答える
0

subprocess.Popenがトリックを実行する必要があります。

この前の答えをチェックしてください: Pythonから非同期で外部コマンドを実行するにはどうすればよいですか?

于 2013-02-05T21:59:43.057 に答える
0

+ " & "それぞれの最後に置くだけで何が問題になりos.system(...)ますか?

それぞれが機能するかどうかにかかわらず、あまり気にしないようですblender

見た目からは、シェルスクリプトでそれを行うことができます。

次のようなものをインストールbeanstalkdして、10台のサーバーにそれぞれ共有キューからジョブをプルするワーカーを実行させることができます。次に、ジョブディスパッチャに、ファイル名、開始フレーム、終了フレームに言及しているジョブを配置してもらいます。

利点は、コンシューマーが終了すると、ステータスをキューに戻すことができることです。

そうしないと、サブプロセスの1つが失敗したかどうかを知るのに問題が発生します。

于 2013-02-05T22:21:32.297 に答える
0

psshのようなツールを使用することをお勧めします。
このツールはマルチスレッドを使用し、高速に実行されます。あなたはここで
それについてもっと読むことができます。

于 2017-01-03T10:45:52.037 に答える