如何读取子进程的第一个字节';在Python中使用stdout,然后丢弃其余的?

如何读取子进程的第一个字节';在Python中使用stdout,然后丢弃其余的?,python,stream,subprocess,Python,Stream,Subprocess,我想读取子进程stdout的第一个字节,以知道它已开始运行。之后,我想放弃所有进一步的输出,这样我就不必担心缓冲区了 最好的方法是什么 澄清:我希望子流程继续与我的程序一起运行,我不想等待它终止或诸如此类的事情。理想情况下,有一些简单的方法可以做到这一点,而不必求助于线程、分叉或多处理 如果忽略输出流,或者忽略它,如果发送的数据超过了缓冲区的容量,就会导致错误。这似乎可行,但感觉不习惯 #!/usr/bin/env python3.1 import threading import subpro

我想读取子进程stdout的第一个字节,以知道它已开始运行。之后,我想放弃所有进一步的输出,这样我就不必担心缓冲区了

最好的方法是什么

澄清:我希望子流程继续与我的程序一起运行,我不想等待它终止或诸如此类的事情。理想情况下,有一些简单的方法可以做到这一点,而不必求助于
线程
分叉
多处理


如果忽略输出流,或者忽略它,如果发送的数据超过了缓冲区的容量,就会导致错误。

这似乎可行,但感觉不习惯

#!/usr/bin/env python3.1
import threading
import subprocess

def discard_stream_while_running(stream, process):
    while process.poll() is None:
        stream.read(1024)

def discard_subprocess_pipes(process, out=True, err=True, in_=True):
    if out and process.stdout is not None and not process.stdout.closed:
        t = threading.Thread(target=discard_stream_while_running, args=(process.stdout, process))
        t.start()

    if err and process.stderr is not None and not process.stderr.closed:
        u = threading.Thread(target=discard_stream_while_running, args=(process.stderr, process))
        u.start()

    if in_ and process.stdin is not None and not process.stdin.closed:
        process.stdin.close()
示例/测试用法
如果名称=“\uuuuu main\uuuuuuuu”:
导入临时文件
导入文本包装
导入时间
将tempfile.NamedTemporaryFile(“w+t”,prefix=“example-”,suffix=“.py”)作为f:
f、 写入(textwrap.dedent(“”)
导入系统
导入时间
sys.stderr.write(“{}字节)通过stdin读取。\\n”
.format(len(sys.stdin.read()))
#将几MB/s的速度推送到标准输出,将消息推送到标准输出。
尽管如此:
sys.stdout.write(“Hello Parent\\n”*1000000)
sys.stderr.write(“子进程写入数据\\n”)
睡眠时间(0.5)
"""))
f、 刷新()
p=subprocess.Popen([“python3.1”,f.name],
stdout=子流程.PIPE,
stdin=子流程(管道)
p、 stdin.write(“Hello Child\n”.encode())

discard_subprocess_pipes(p)#如果您使用的是Python3.3+,那么可以使用
DEVNULL
stdout
stderr
特殊值来丢弃子流程输出

from subprocess import Popen, DEVNULL

process = Popen(["mycmd", "myarg"], stdout=DEVNULL, stderr=DEVNULL)
或者,如果您使用的是Python 2.4+,则可以通过以下方式进行模拟:

import os
from subprocess import Popen

DEVNULL = open(os.devnull, 'wb')
process = Popen(["mycmd", "myarg"], stdout=DEVNULL, stderr=DEVNULL)

但是,这并不能让您有机会读取标准输出的第一个字节。

我的答案是否不完全符合您的要求?启动子进程,读取第一个字节,然后继续并行运行进程……据我所知,它将继续将
stdout
stderr
读入缓冲区,从而浪费内存。我不确定,但如果缓冲区填满,这也可能导致子进程阻塞。我想避免这种情况。他的解决方案不会阻塞,因为它不会读取超过第一个字节的内容。但你不知道什么时候完成<代码>等待
不会读取任何内容,但可能会阻塞(如果程序写入太多,并开始等待操作系统读取管道)。我的
无法通信
,它会读取内容,占用内存。但是如果不阅读,你就无法知道过程何时结束。。。让我再举一个例子solution@Jeremy我修改了我的示例以证明没有内存被浪费。使用进程监视器运行并观察进程的内存使用情况。它从不上升。我已经对它进行了测试,第二个进程阻塞一次,第一个进程中的缓冲区已满。换句话说,它没有回答问题。它回答了文章标题中的问题。因此,我认为它对在internet搜索中访问此页面的其他人很有用。这是否会干扰
子流程。检查调用
?我不这么认为,因为退出状态是由
wait
给出的,但这只是为了确定。这种技术也适用于check_调用,因为它采用与Popen相同的参数。
DEVNULL
对我不起作用。我使用的是Python 3.2.3,您不会等待读取第一个字节。尽管如此:
p.poll()在
Popen()之后为None
表示子进程正在运行。如果这是你所需要的,那么你应该。
import os
from subprocess import Popen

DEVNULL = open(os.devnull, 'wb')
process = Popen(["mycmd", "myarg"], stdout=DEVNULL, stderr=DEVNULL)