Python 2.7和3.3的子进程模块区别

3
我有以下代码。
from __future__ import print_function
import subprocess

p = subprocess.Popen(['cat'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p.kill()
p.wait()
print(p.stdin.write(b'some'))

我用Python 2.7和Python 3.3运行它。在Python 2.7中,当我尝试写入stdin时,会抛出异常。而在Python 3.3中,这段代码打印4。Python 2.7的subprocess模块与Python 3.3有什么区别?


文档中同时提供了2.73.3版本,警告使用communicate而不是.stdin.write - 这有什么区别吗? - jonrsharpe
1
知道在Python 2.7中抛出哪个表达式会很好 :) - jbaiter
异常是 IOError: [Errno 32] Broken pipe。当我使用 communicate 时,不会抛出异常,但是我需要使用 stdin.write - sinitsynsv
你为什么要先杀死进程,然后再写入它的标准输入?在我看来,这只会导致未定义的行为。 - Kritzefitz
2
你真正想做什么?要优雅地处理子进程死亡的情况吗?在哪个平台上?如果在末尾加入p.stdin.flush(),在3.3上是否会出现异常? - Janne Karila
是的,我正在尝试处理子进程死亡的情况。平台是Linux。如果我添加p.stdin.flush(),我会得到一个异常。 - sinitsynsv
1个回答

6
区别在于bufsize的默认值。在Python 2.7中,它是0(无缓冲),因此write会导致EPIPE错误。在Python 3.2+中,管道是完全缓冲的,即在刷新缓冲区之前,不会检测到任何错误。从subprocess的文档中可以看到:

自版本3.3.1起更改:bufsize现在默认为-1,以启用默认缓冲以匹配大多数代码所期望的行为。在Python 3.2.4和3.3.1之前的版本中,它错误地默认为0,这是无缓冲的并允许短读取。这是无意的,并且与大多数代码期望的Python 2的行为不符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接