如何查明为什么subprocess.Popen的wait()在stdout=PIPE时永远等待?
我有一个程序,它会向标准输出(stdout)和可能的标准错误输出(stderr)写数据。我想从Python中运行这个程序,并捕获它的标准输出和标准错误输出。我的代码是这样的:
from subprocess import *
p = Popen( exe, shell=TRUE, stdout=PIPE, stderr=PIPE )
rtrncode = p.wait()
对于几个程序,这样做没问题,但当我添加一个新的程序时,它就一直卡在那里,动不了。如果我去掉 stdout=PIPE
,这个程序就会把输出直接写到控制台,然后正常结束,一切都很好。那么,我该怎么找出导致卡住的原因呢?
我在Windows XP上使用Python 2.5。这个程序不从标准输入(stdin)读取数据,也没有任何用户输入的要求(比如“按一个键”)。
2 个回答
3
看看这个文档。里面说不要使用wait,因为这样可能会导致程序卡住。可以试试用communicate这个方法。
53
当一个管道的缓冲区填满了(通常大约是4KB),写入的进程就会停止,直到有读取的进程读取了一些数据;但是在这里,你什么都没有读取,直到子进程完成,这就导致了死锁。文档对wait
的解释非常清楚:
警告 如果子进程向标准输出或标准错误输出管道生成了足够多的输出,导致它阻塞在等待操作系统的管道缓冲区接受更多数据,这将会导致死锁。使用
communicate
可以避免这个问题。
如果因为某种原因你不能使用communicate
,可以让子进程把数据写入一个临时文件,然后你可以wait
并在准备好时读取那个文件——写入文件而不是管道,就不会有死锁的风险。