1. ホーム
  2. python

[解決済み] サブプロセス呼び出しのブロッキングとノンブロッキング

2023-08-29 10:50:32

質問

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

どれがブロッキングで、どれがブロッキングでないか?

私が言いたいのは、もし私が subprocess.Popen() を使用した場合、親プロセスは子プロセスを待つのか、それとも return / exit を実行し続ける前に

どのようにして shell=True はこれらの呼び出しにどのように影響するのでしょうか?

どのように解決するのですか?

Popen はノンブロッキングです。 callcheck_call はブロック化されます。 をブロックさせることができます。 Popen インスタンスをブロックさせるには、その wait または communicate メソッドを使用します。

を見ると を見ると、ソースコード を見ると call が呼び出されます。 Popen(...).wait() を呼び出すので、ブロックされているのです。 check_call が呼び出す call を呼び出すので、同様にブロックされます。

厳密には shell=True はブロッキングの問題と直交しています。しかし shell=True はPythonにシェルを実行させ、そのシェルでコマンドを実行させます。ブロッキングコールを使用した場合、コールが返されるのは シェル が終了したときに返されます。シェルはコマンドを実行するためにサブプロセスを生成するかもしれないので、生成されたサブプロセスよりも先にシェルが終了するかもしれません。例えば

import subprocess
import time

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

ここでは 2 つのプロセスが生成されています。Popen はシェルを実行している一つのサブプロセスを生成します。シェルは今度は ls . proc.terminate() を実行するとシェルは終了しますが ls を実行しているサブプロセスは残ります。(これは python スクリプトが終了した後でも、大量の出力によって明らかになります。を殺す準備をしておいてください。 ls を殺す準備をしておいてください。 pkill ls .)