如果stdout = PIPE,我如何找出为什么subprocess.Popen wait() 永远等待? [英] How can I find out why subprocess.Popen wait() waits forever if stdout=PIPE?

查看:17
本文介绍了如果stdout = PIPE,我如何找出为什么subprocess.Popen wait() 永远等待?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个写入标准输出和可能标准错误的程序.我想从 python 运行它,捕获标准输出和标准错误.我的代码如下:

I have a program that writes to stdout and possibly stderr. I want to run it from python, capturing the stdout and stderr. My code looks like:

from subprocess import *

p = Popen( exe, shell=TRUE, stdout=PIPE, stderr=PIPE )
rtrncode = p.wait()

对于几个程序,这可以正常工作,但是当我添加一个新程序时,新程序会永远挂起.如果我删除 stdout=PIPE,程序会将其输出写入控制台并完成,一切都很好.如何确定导致挂起的原因?

For a couple of programs, this works fine, but when I added a new one, the new one hangs forever. If I remove stdout=PIPE, the program writes its output to the console and finishes and everything is fine. How can I determine what's causing the hang?

在 Windows XP 上使用 python 2.5.该程序不会从标准输入读取数据,也没有任何类型的用户输入(即按下键").

Using python 2.5 on Windows XP. The program does not read from stdin nor does it have any kind of user input (i.e. "hit a key").

推荐答案

当管道的缓冲区填满时(通常为 4KB 左右),写入过程停止,直到读取过程读取了一些有问题的数据;但是在这里,在子进程完成之前,您什么都没有读取,因此出现了死锁.The docs on wait 把它确实非常清楚:

When a pipe's buffer fills up (typically 4KB or so), the writing process stops until a reading process has read some of the data in question; but here you're reading nothing until the subprocess is done, hence the deadlock. The docs on wait put it very clearly indeed:

警告如果子进程产生足够的输出到 stdout 或 stderr 管道,这样它阻塞等待操作系统管道缓冲区以接受更多数据.利用communicate() 来避免这种情况.

Warning This will deadlock if the child process generates enough output to a stdout or stderr pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

如果由于某种原因您不能使用 communicate,请让子进程写入一个临时文件,然后您可以 wait 并在该文件准备好时读取该文件 -- 写入文件而不是管道,不会有死锁的风险.

If you can't use communicate for some reason, have the subprocess write to a temporary file, and then you can wait and read that file when it's ready -- writing to a file, instead of to a pipe, does not risk deadlock.

这篇关于如果stdout = PIPE,我如何找出为什么subprocess.Popen wait() 永远等待?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆