python 如果 stdout=PIPE,我如何找出 subprocess.Popen wait() 为什么会永远等待?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1445627/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 22:15:35  来源:igfitidea点击:

How can I find out why subprocess.Popen wait() waits forever if stdout=PIPE?

pythonsubprocess

提问by Graeme Perrow

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:

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

from subprocess import *

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

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?

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

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").

在 Windows XP 上使用 python 2.5。该程序不从标准输入读取,也不具有任何类型的用户输入(即“击键”)。

回答by Alex Martelli

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 docson waitput it very clearly indeed:

当管道的缓冲区填满时(通常为 4KB 左右),写入过程将停止,直到读取过程读取了一些相关数据;但是在这里,在子流程完成之前,您什么也读不到,因此陷入僵局。 该文档wait说得非常清楚确实是:

WarningThis 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.

警告如果子进程向 stdout 或 stderr 管道生成足够的输出,从而阻止等待 OS 管道缓冲区接受更多数据,这将导致死锁。使用communication() 来避免这种情况。

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

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

回答by MitMaro

Take a look at the docs. It states that you shouldn't use wait as it can cause a dead lock. Try using communicate.

看看文档。它指出您不应该使用等待,因为它会导致死锁。尝试使用交流