##
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*` クラスが提供する各々のファイルに対して、個別のスレッドを使って 読み出しを行います。