简体   繁体   English

Python:如何从另一个进程读取stdout非阻塞?

[英]Python: How to read stdout non blocking from another process?

During the runtime of a process I would like to read its stdout and write it to a file. 在进程的运行期间,我想读取它的标准输出并将其写入文件。 Any attempt of mine however failed because no matter what I tried as soon as I tried reading from the stdout it blocked until the process finished. 然而,我的任何尝试都失败了,因为无论我尝试从stdout读取它尝试了什么,它一直阻止,直到过程结束。

Here is a snippet of what I am trying to do. 这是我想要做的事情的片段。 (The first part is simply a python script that writes something to stdout.) (第一部分只是一个将内容写入stdout的python脚本。)

import subprocess

p = subprocess.Popen('python -c \'\
from time import sleep\n\
for i in range(3):\n\
    sleep(1)\n\
    print "Hello", i\
\'', shell = True, stdout = subprocess.PIPE)

while p.poll() == None:
    #read the stdout continuously
    pass

print "Done"

I know that there are multiple questions out there that deal with the same subject. 我知道有很多问题涉及同一主题。 However, none of the ones I found was able to answer my question. 但是,我找到的没有一个能够回答我的问题。

What is happening is buffering on the writer side. 正在发生的事情是在作家方缓冲。 Since you are writing such small chunks from the little code snippet the underlying FILE object is buffering the output until the end. 由于您是从小代码片段中编写这样的小块,因此基础FILE对象将缓冲输出直到结束。 The following works as you expect. 以下按预期工作。

#!/usr/bin/python

import sys
import subprocess

p = subprocess.Popen("""python -c '
from time import sleep ; import sys
for i in range(3):
    sleep(1)
    print "Hello", i
    sys.stdout.flush()
'""", shell = True, stdout = subprocess.PIPE)

while True:
    inline = p.stdout.readline()
    if not inline:
        break
    sys.stdout.write(inline)
    sys.stdout.flush()

print "Done"

However, you may not be expecting the right thing. 但是,你可能不会期待正确的事情。 The buffering is there to reduce the number of system calls in order to make the system more efficient. 缓冲用于减少系统调用的数量,以使系统更有效。 Does it really matter to you that the whole text is buffered until the end before you write it to a file? 在将文本写入文件之前,将整个文本缓冲到最后是否真的很重要? Don't you still get all the output in the file? 你还没有得到文件中的所有输出吗?

the following code would print stdout line by line as the subprocess runs until the readline() method returns an empty string: 当子进程运行时,以下代码将逐行打印stdout,直到readline()方法返回一个空字符串:

p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
for line in iter(p.stdout.readline, ''):
    print line
p.stdout.close()
print 'Done'

update relating to your question better: 更新与您的问题相关的更新:

import subprocess

p = subprocess.Popen(['python'], stdout=subprocess.PIPE, stdin=subprocess.PIPE)
p.stdin.write("""
from time import sleep ; import sys
for i in range(3):
    sleep(1)
    print "Hello", i
    sys.stdout.flush()
""")
p.stdin.close()
for line in iter(p.stdout.readline, ''):
    print line
p.stdout.close()
print 'Done'

You can use subprocess.communicate() to get the output from stdout. 您可以使用subprocess.communicate()从stdout获取输出。 Something like: 就像是:

while(p.poll() == None):
    #read the stdout continuously
    print(p.communicate()[0])
    pass

More info available at: http://docs.python.org/library/subprocess.html 有关更多信息,请访问: http//docs.python.org/library/subprocess.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM