阻止读取python中的子进程.PIPE

我读了关于python中的subprocess.PIPE的非阻塞读取的问题/回答/评论,但我觉得有点欠缺。

当我实施所提供的解决方案时,我注意到当子流程自行结束时,这种方法效果最佳。 但是,如果子进程提供了一个信息流,而且我们正在寻找输出的单个匹配项,那么这种方法不适合我的需求(特别是对Windows而言,如果这很重要的话)。

这是我的示例:ping.py

import time

def main():
    for x in range(100):
        print x
        time.sleep(1)

if __name__ == '__main__':
    print("Starting")
    time.sleep(2)
    main()

runner.py

import subprocess
import time
import sys
from Queue import Queue, Empty
from threading  import Thread

def enqueue_output(out, queue):
    for line in iter(out.readline, b''):
        queue.put(line)
    out.close()

#Start process we want to listen to
pPing = subprocess.Popen('ping.py', 
    shell=True,
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    )

q = Queue()
t = Thread(target=enqueue_output, args=(pPing.stdout, q))
t.daemon = True
t.start()

#make sure it's started  
print ("get the first line")
try:
    line = q.get()
except Empty:
    pass
else:
    print line.strip()

#look for the 'magic' output
print("empty the queue")
while not q.empty():
    line = q.get_nowait().strip()
    if (line == "3"):
        print("got it!")
        sys.exit()
    else:
        print("not yet")

我的期望是,跑步者将确保过程开始,然后等待魔术输出,然后停下来,然后停止。 但是,子流程运行的时间越长,跑步者运行的时间越长。 但是因为'魔术'的输出相对来说比较快,所以我必须等到子进程结束后再进行任何处理。

我错过了什么?

谢谢,罗伯特


好的,如果我正确理解你正在尝试做什么,问题是ping仍然是跑步者的子进程。 尽管可以使读取调用非阻塞,但父进程在孩子仍在运行时不会实际退出。 如果您希望跑步者不要等待孩子完成,请阅读第一行和第一个魔术输出,然后退出,您需要ping来解除自己与父进程的关联。 看看这个代码示例,看看这是如何完成http://www.jejik.com/articles/2007/02/a_simple_unix_linux_daemon_in_python/。 当然,您可以跳过关闭并重新打开所有I / O流的部分。

在同样的说明中,我不确定将一个开放的I / O流连接到父节点将允许父节点退出,所以如果这恰好是一个问题,您可能需要找出另一种交换数据的方式。

链接地址: http://www.djcxy.com/p/52499.html

上一篇: blocking read on a subprocess.PIPE in python

下一篇: Non blocking read on os.pipe on Windows