web-dev-qa-db-ja.com

ブロッキングおよび非ブロッキングのサブプロセス呼び出し

私はsubprocess.call()subprocess.Popen()subprocess.check_call()の間で完全に混乱しています。

どちらがブロックされており、どれがそうではありませんか?

私が言いたいのは、subprocess.Popen()を使用する場合、親プロセスが実行を続ける前に子プロセスがreturn/exitになるのを待つかどうかです。

どうやって Shell=Trueこれらの呼び出しに影響しますか?

57
Roshan Mehta

Popenはノンブロッキングです。 callおよびcheck_callはブロックしています。 Popenまたはwaitメソッドを呼び出すことで、communicateインスタンスブロックを作成できます。

ソースコード を見ると、callPopen(...).wait()を呼び出していることがわかります。これがブロックされている理由です。 check_callcallを呼び出します。これが同様にブロックする理由です。

厳密に言えば、Shell=Trueはブロッキングの問題と直交しています。ただし、Shell=Trueは、Pythonを実行してシェルでコマンドを実行します。ブロッキング呼び出しを使用する場合、呼び出しはShell が終了します。シェルはコマンドを実行するサブプロセスを生成するため、シェルは生成されたサブプロセスの前に終了する場合があります。

import subprocess
import time

proc = subprocess.Popen('ls -lRa /', Shell=True)
time.sleep(3)
proc.terminate()
proc.wait()

ここでは、2つのプロセスが生成されます。Popenは、シェルを実行する1つのサブプロセスを生成します。シェルは、lsを実行するサブプロセスを順番に生成します。 proc.terminate()はシェルを強制終了しますが、lsを実行しているサブプロセスは残ります。 (これは、pythonスクリプトが終了した後でも、大量の出力によって明示されます。pkill lslsを強制終了する準備をしてください。)

83
unutbu