17.5. popen2 —アクセス可能なI / Oストリームを持つサブプロセス—Pythonドキュメント
17.5。 popen2 —アクセス可能なI / Oストリームを持つサブプロセス
バージョン2.6以降非推奨:このモジュールは廃止されました。 サブプロセスモジュールを使用します。 特に古い関数をサブプロセスモジュールセクションに置き換えるを確認してください。
このモジュールを使用すると、プロセスを生成して入力/出力/エラーパイプに接続し、UnixおよびWindowsでリターンコードを取得できます。
サブプロセスモジュールは、新しいプロセスを生成してその結果を取得するためのより強力な機能を提供します。 popen2 モジュールを使用するよりも、サブプロセスモジュールを使用することをお勧めします。
このモジュールが提供する主要なインターフェースは、3つのファクトリー関数です。 これらのそれぞれについて、 bufsize が指定されている場合、I / Oパイプのバッファーサイズを指定します。 mode が指定されている場合は、文字列'b'
または't'
である必要があります。 Windowsでは、これはファイルオブジェクトをバイナリモードで開くかテキストモードで開くかを決定するために必要です。 モードのデフォルト値は't'
です。
Unixでは、 cmd はシーケンスである可能性があり、その場合、引数はシェルの介入なしにプログラムに直接渡されます( os.spawnv()の場合と同様)。 cmd が文字列の場合、シェルに渡されます( os.system()と同様)。
子プロセスの戻りコードを取得する唯一の方法は、 Popen3 および Popen4 クラスでpoll()
またはwait()
メソッドを使用することです。 これらはUnixでのみ利用可能です。 この情報は、 popen2()、 popen3()、 popen4()関数、または osの同等の関数を使用している場合は利用できません。 モジュール。 ( os モジュールの関数によって返されるタプルは、 popen2 モジュールによって返されるタプルとは異なる順序であることに注意してください。)
- popen2.popen2(cmd[, bufsize[, mode]])
- cmd をサブプロセスとして実行します。 ファイルオブジェクト
(child_stdout, child_stdin)
を返します。
- popen2.popen3(cmd[, bufsize[, mode]])
- cmd をサブプロセスとして実行します。 ファイルオブジェクト
(child_stdout, child_stdin, child_stderr)
を返します。
- popen2.popen4(cmd[, bufsize[, mode]])
cmd をサブプロセスとして実行します。 ファイルオブジェクト
(child_stdout_and_stderr, child_stdin)
を返します。バージョン2.0の新機能。
Unixでは、ファクトリ関数によって返されるオブジェクトを定義するクラスも利用できます。 これらはWindowsの実装には使用されず、そのプラットフォームでは使用できません。
- class popen2.Popen3(cmd[, capturestderr[, bufsize]])
このクラスは子プロセスを表します。 通常、 Popen3 インスタンスは、上記の popen2()および popen3()ファクトリ関数を使用して作成されます。
ヘルパー関数の1つを使用して Popen3 オブジェクトを作成しない場合、パラメーター cmd はサブプロセスで実行するシェルコマンドです。 captionstderr フラグは、trueの場合、オブジェクトが子プロセスの標準エラー出力をキャプチャする必要があることを指定します。 デフォルトはfalseです。 bufsize パラメーターが指定されている場合、子プロセスとの間のI / Oバッファーのサイズを指定します。
- class popen2.Popen4(cmd[, bufsize])
Popen3 に似ていますが、常に標準エラーを標準出力と同じファイルオブジェクトにキャプチャします。 これらは通常、 popen4()を使用して作成されます。
バージョン2.0の新機能。
17.5.1。 Popen3およびPopen4オブジェクト
Popen3 および Popen4 クラスのインスタンスには、次のメソッドがあります。
- Popen3.poll()
- 子プロセスがまだ完了していない場合は
-1
を返し、そうでない場合はそのステータスコード( wait()を参照)を返します。
- Popen3.wait()
- 子プロセスのステータスコードを待機して返します。 ステータスコードは、プロセスのリターンコードと、
exit()
システムコールを使用して終了したか、シグナルが原因で終了したかに関する情報の両方をエンコードします。 ステータスコードの解釈に役立つ関数は、 os モジュールで定義されています。W*()
ファミリーの機能については、セクションプロセス管理を参照してください。
次の属性も使用できます。
- Popen3.fromchild
- 子プロセスからの出力を提供するファイルオブジェクト。 Popen4 インスタンスの場合、これにより、標準出力と標準エラーストリームの両方が提供されます。
- Popen3.tochild
- 子プロセスに入力を提供するファイルオブジェクト。
- Popen3.childerr
- コンストラクターに対して capturestderr がtrueの場合、子プロセスからのエラー出力を提供するファイルオブジェクト。それ以外の場合は、
None
。 Popen4 インスタンスの場合、これは常にNone
になります。
- Popen3.pid
- 子プロセスのプロセスID。
17.5.2。 フロー制御の問題
あらゆる形式のプロセス間通信を使用する場合は常に、制御フローを慎重に検討する必要があります。 これは、このモジュール(または os モジュールの同等物)によって提供されるファイルオブジェクトの場合に当てはまります。
親が子の標準出力から読み取っているときに、大量のデータを標準エラーに書き込む子プロセスからの出力を読み取ると、デッドロックが発生する可能性があります。 同様の状況は、読み取りと書き込みの他の組み合わせでも発生する可能性があります。 重要な要素は、_PC_PIPE_BUF
バイトを超えるバイトが一方のプロセスによってブロック方式で書き込まれ、もう一方のプロセスが最初のプロセスからもブロッキング方式で読み取られることです。
この状況に対処する方法はいくつかあります。
多くの場合、最も単純なアプリケーションの変更は、親プロセスでこのモデルに従うことです。
import popen2
r, w, e = popen2.popen3('python slave.py')
e.readlines()
r.readlines()
r.close()
e.close()
w.close()
子にこのようなコードを使用すると、次のようになります。
import os
import sys
# note that each of these print statements
# writes a single long string
print >>sys.stderr, 400 * 'this is a test\n'
os.close(sys.stderr.fileno())
print >>sys.stdout, 400 * 'this is another test\n'
特に、sys.stderr
はすべてのデータを書き込んだ後に閉じる必要があることに注意してください。そうしないと、readlines()
は返されません。 また、sys.stderr.close()
はstderr
を閉じないため、 os.close()を使用する必要があることに注意してください(そうでない場合、sys.stderr
に割り当てるとサイレントに閉じます。したがって、これ以上エラーを出力することはできません)。
より一般的なアプローチをサポートする必要があるアプリケーションは、パイプを介したI / Oを select()ループと統合するか、個別のスレッドを使用して、popen*()
関数によって提供される個々のファイルを読み取る必要があります。またはPopen*
クラスが使用されました。