8

close_fdsPython27 で問題が発生したため、いくつかの調査を行った後、次のを見つけました。

from subprocess import Popen, PIPE, STDOUT
p1 = Popen(['cat'], stdin=PIPE, stdout=PIPE)
p2 = Popen(['grep', 'a'], stdin=p1.stdout, stdout=PIPE)
p1.stdin.write("aaaaaaaaaaaaaaaa\n")
p1.stdin.close()
p2.stdout.read()

私の問題は、なぜp1.stdin開いたままなのか理解できないことです。p1の子ではないp2ため、明示的に渡されたもの以外のリソースをp2継承するべきではありません。さらに、なぜ設定すると問題が解決するのですか? ここにこう書かれています。p1p1.stdoutclose_fds=Truep2

close_fds が true の場合、子プロセスが実行される前に、0、1、および 2 を除くすべてのファイル記述子が閉じられます。

したがって、 と の間の継承が理解できたとしてp1も、標準入力 (1) であるため、閉じてはなりp2ませp1.stdinん。close_fds=True

4

1 に答える 1

13

p1とは兄弟であるためp2、対応するプロセス間で直接継承が行われることはありません。

ただし、親が として認識しp1.stdin、 によって継承されp1、その にリダイレクトされるファイル記述子を考慮してstdinください。このファイル記述子は親プロセスに存在し (0、1、または 2 以外の番号で - 印刷することで確認できますp1.stdin.fileno())、存在する必要があります。これは、親プロセスから書き込みを行うためです。によって意図せずに継承され、開かれたままになっているのは、このファイル記述子ですp2

の場合のように、開いているファイルが複数のファイル記述子によって参照されている場合、すべての記述子が閉じp1.stdinられたときにのみ閉じられます。これが、 closeとpassの両方が必要な理由です。(生成コードを手動で実装した場合は、2 番目の の後にファイル記述子を単純に閉じます。)p1.stdin close_fdsp2fork()

于 2013-11-13T09:47:18.820 に答える