subprocess.Popen()
を使用して、同じアプリケーションの複数のインスタンスを自分のpythonスクリプトを使用して同時に実行するスクリプトから生成します。いくつかの問題が発生します。各スレッドでアプリケーションを実行します。 popen()
呼び出しを使用し、callingwait()
で終了するのを待ちます。問題は、wait()
- callが実際にプロセスを終了します。1つのスレッドのみを使用し、プロセスの開始時と終了時にテキストメッセージを出力して実験しました。したがって、スレッド関数は次のようになります。
_def worker():
while True:
job = q.get() # q is a global Queue of jobs
print('Starting process %d' % job['id'])
proc = subprocess.Popen(job['cmd'], Shell=True)
proc.wait()
print('Finished process %d' % job['id'])
job.task_done()
_
ただし、使用するスレッドが1つだけの場合でも、「Finished process ...」メッセージが表示される前に、いくつかの「Starting process ...」メッセージが出力されます。 wait()
が実際に待機しない場合はありますか?いくつかの異なる外部アプリケーション(C++コンソールアプリケーション)があり、同時に複数のインスタンスが実行されます。それらの一部では私のコードは機能しますが、他の場合は機能しません。 wait()
の呼び出しに何らかの影響を与える外部アプリケーションに問題があるのでしょうか?スレッドを作成するためのコードは次のようになります。
_for i in range(1):
t = Thread(target=worker)
t.daemon = True
t.start()
q.join() # Wait for the queue to empty
_
pdate 1:一部の外部アプリケーションでは、-1073471801の戻りコード(_proc.returncode
_)が表示されることもあります。たとえば、外部アプリケーションの1つがその戻りコードに最初の2回Popen
が呼び出されるが、最後の2つは呼び出されない(4つのジョブがある場合)。
pdate 2:明確にするために、現在、キューに4つのジョブがあり、4つの異なるテストケースがあります。コードを実行すると、外部アプリケーションの1つで、最初の2つのPopen
- callsが戻りコード-1073471801を生成します。しかし、Popen
が呼び出す正確なコマンドを出力してコマンドウィンドウで実行すると、問題なく実行されます。
解決済み!自分が抱えていた問題をなんとか解決しました。問題は、スレッドプログラミングの経験の欠如にあったと思います。最初のワーカースレッドを作成したとき、pythonスクリプトが終了するまで、それらは存続し続けるという事実を逃しました。誤って、キューに新しいアイテムを置くたびに、より多くのワーカースレッドを作成しました(実行する外部プログラムごとにバッチで実行します。)したがって、4番目の外部アプリケーションに到達するまでに、1つしかないと思っていたとしても、4つのスレッドが同時に実行されていました。
Popenの代わりに check_call()
を使用することもできます。 check_call()
は、Shell=True
し、ジョブの終了コードを返します。
悲しいことに、Shell=True
を使用してサブプロセスを実行すると、 wait(
) は、コマンドsh
ではなく、cmd
サブプロセスが完了するまで待機します。
Shell=True
を使用できない場合は、このようにプロセスグループを作成できます answer を使用して os.waitpid を使用することをお勧めしますシェルプロセスだけでなく、プロセスグループを待機します。
これがお役に立てば幸いです:)
私も問題を抱えていましたが、あなたの影響を受けました。
鉱山は次のように見え、美しく機能します。
startupinfo = subprocess.STARTUPINFO()
startupinfo.dwFlags = subprocess.STARTF_USESHOWWINDOW
startupinfo.wShowWindow = subprocess.SW_HIDE
proc = subprocess.Popen(command, startupinfo=startupinfo)
proc.communicate()
proc.wait()
これもウィンドウを非表示にしていることに注意してください。
呼び出しているすべてのアプリケーションに、終了時に有効なシステム戻りコードがあることを確認してください。