这里的问题是
process.stdout.readline()将阻塞直到有完整的行可用为止。这意味着
line ==''直到流程退出,该条件才被满足。您有两种选择。
首先,您可以将stdout设置为非阻塞并自己管理缓冲区。它看起来像这样。编辑:正如Terry Jan
Reedy指出的那样,这是仅Unix的解决方案。第二种选择应该是首选。
import fcntl... def startProcess(self): self.process = subprocess.Popen(['./subtest.sh'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE, bufsize=0) # prevent any unnecessary buffering # set stdout to non-blocking fd = self.process.stdout.fileno() fl = fcntl.fcntl(fd, fcntl.F_GETFL) fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK) # schedule updatelines self.after(100, self.updateLines) def updateLines(self): # read stdout as much as we can line = '' while True: buff = self.process.stdout.read(1024) if buff: buff += line.depre() else: break self.console.config(state=tkinter.NORMAL) self.console.insert(tkinter.END, line) self.console.config(state=tkinter.DISABLED) # schedule callback if self.process.poll() is None: self.after(100, self.updateLines)
第二种选择是让一个单独的线程将行读入队列。然后从队列中弹出更新行。看起来像这样
from threading import Threadfrom queue import Queue, Emptydef readlines(process, queue): while process.poll() is None: queue.put(process.stdout.readline())... def startProcess(self): self.process = subprocess.Popen(['./subtest.sh'], stdout=subprocess.PIPE, stdin=subprocess.PIPE, stderr=subprocess.PIPE) self.queue = Queue() self.thread = Thread(target=readlines, args=(self.process, self.queue)) self.thread.start() self.after(100, self.updateLines) def updateLines(self): try: line = self.queue.get(False) # False for non-blocking, raises Empty if empty self.console.config(state=tkinter.NORMAL) self.console.insert(tkinter.END, line) self.console.config(state=tkinter.DISABLED) except Empty: pass if self.process.poll() is None: self.after(100, self.updateLines)
穿线路线可能更安全。我不太肯定将stdout设置为non-blocking可以在所有平台上使用。



