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

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

问题描述

我有一个写入标准输出和可能的标准错误的程序.我想从 python 运行它,捕获 stdout 和 stderr.我的代码看起来像:

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.该程序不从 stdin 读取,也没有任何类型的用户输入(即点击一个键").

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 左右)时,写入过程将停止,直到读取过程读取了一些有问题的数据;但是在这里,在子流程完成之前,您什么也读不到,因此陷入了僵局.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 管道,这样它阻塞等待操作系统管道缓冲区以接受更多数据.用沟通()以避免这种情况.

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天全站免登陆