1

次のコードは正しく終了し、

import subprocess

p = subprocess.Popen("cat", stdin=subprocess.PIPE)
p.stdin.close()
p.wait()
print p.returncode

しかし、次のコードは決して終わりません。

import subprocess

p1 = subprocess.Popen("cat", stdin=subprocess.PIPE)
p2 = subprocess.Popen("cat", stdin=subprocess.PIPE)
p1.stdin.close()
p1.wait()
p2.stdin.close()
p2.wait()

print p1.returncode, p2.returncode

ドクター曰く、

警告 子プロセスが stdout または stderr パイプに十分な出力を生成し、OS パイプ バッファーがさらにデータを受け入れるのを待ってブロックする場合、これはデッドロックになります。これを回避するには、communicate() を使用します。

ただし、この場合、出力は生成されません。なぜ行き詰まりますか?

私は Linux を使用しており、python2.5 と 2.6 の両方を試しました。

--

編集

MacOSXでpython2.7.1と3.2.3も試しました。結果は以下の通り

  • 2.5.2(linux) -> デッドロック
  • 2.6.6(linux) -> デッドロック
  • 2.7.1(osx) -> デイドロック
  • 3.2.3(osx) -> OK!

これは古いpythonのバグですか?回避策はありますか?

4

1 に答える 1

2

最後に、私は自分で答えに気づきました。

close_fds=TruePopen()を呼び出すために必要です。Popenはそうするので、親プロセスだけpipe(2)fork(2)なく子プロセスもパイプの出力側を閉じる必要があります。新しいPythonでのみ、close_fds=Trueがデフォルトのようです。

とにかくありがとう ;)

于 2013-02-22T11:17:29.030 に答える