首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Python子进程丢失程序标准输出的10%

Python子进程丢失程序标准输出的10%
EN

Stack Overflow用户
提问于 2012-05-21 17:43:59
回答 2查看 2.7K关注 0票数 4

我有一个程序需要调用为一个带有python的子进程。这个程序是用java编写的。是啊我知道..。

无论如何,我需要捕捉所有的输出从上述程序。

不幸的是,当我用通信调用subprocess.popen2或subprocess.Popen时,当我使用分配给stdout的subprocess.PIPE和使用分配给stdout的文件描述符(从打开的返回)时,我损失了大约10%的输出数据。

子流程中的文档非常明确,如果您试图捕获子进程的所有输出,那么使用subprocess.PIPE是不稳定的。

我目前正在使用pexpect将输出转储到一个tmp文件中,但出于显而易见的原因,这需要花费很长时间。

我希望将所有数据保存在内存中,以避免磁盘写入。

欢迎任何推荐!谢谢!

代码语言:javascript
复制
import subprocess

cmd = 'java -Xmx2048m -cp "/home/usr/javalibs/class:/home/usr/javalibs/libs/dependency.jar" --data data --input input" 

# doesn't get all the data
#
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]

OR
# doesn't get all the data
#
fd = open("outputfile",'w')
p = subprocess.Popen(cmd, stdout=fd, shell=True)
p.communicate()
fd.close() # tried to use fd.flush() too.

# also tried
# p.wait() instead of p.communicate(), but wait doesn't really wait for the java program to finish running - it doesn't block

OR
# also fails to get all the data
#
import popen2
(rstdout, rstdin) = popen2.popen2(cmd)

预期输出是一系列ascii线(几千条)。这些行包含一个数字和一行字符的末尾。

代码语言:javascript
复制
0\n
1\n
4\n
0\n
...
EN

回答 2

Stack Overflow用户

发布于 2012-05-21 18:29:10

我使用的subprocessstdout上的输出要大得多,但没有见过这样的问题。很难从你所展示的东西中得出什么是根本原因。我将检查以下情况:

因为p.wait()不为你工作。可能的情况是,当您阅读您的PIPE时,您的java程序仍然忙于打印最后10%。先把p.wait()直接拿出来:

  • 在您阅读PIPE之前插入足够大的等待时间(比如30秒),您的10%会出现吗?
  • 值得怀疑p.wait()没有阻止您的java程序。您的java程序是否进一步对其他program?
  • check ( p.wait()的返回值)进行子处理。您的java程序是否正常终止?

如果问题不在并发模型中,那么检查java程序中的打印是否正确:

  • ,您在java程序中使用了什么函数来打印到stdout?您是否倾向于或忽略IOException
  • Did正确地刷新流?当java程序终止时,最后10%可能在缓冲区中而不进行适当的刷新。
票数 2
EN

Stack Overflow用户

发布于 2012-05-21 19:06:17

这一定是与你实际调用的过程有关的东西。您可以通过使用另一个响应行的python脚本进行简单测试来验证这一点:

out.py

代码语言:javascript
复制
import sys

for i in xrange(5000):
    print "%d\n" % i

sys.exit(0)

test.py

代码语言:javascript
复制
import subprocess

cmd = "python out.py"
p = subprocess.Popen(cmd, stdout=subprocess.PIPE, shell=True)
output = p.communicate()[0]

print output

因此,您可以验证问题不是数据的大小,而是与您正在调用的进程的通信。

您还应该确认您正在运行的python版本,正如我以前所读过的关于Popen内部缓冲区的问题(但是使用一个单独的文件句柄,就像您通常为我建议的那样)。

如果子进程调用无限期挂起,将是一个缓冲区问题。但是如果这个过程是完成的,只是缺少线条,那么Popen就在做它的工作。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10689998

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档