这与我的另一篇文章multithreading issue with wx.TextCtrl (or underlying GTK+)有关,在纠正了从主线程调用图形用户界面交互后,我发现它又遇到了管道阻塞缓冲问题。那么,如何从subprocess.stdout获得自发输出呢?
简而言之,目前我正在使用subprocess.popen启动一个外部长时间运行的程序。
launchcmd=["EXTERNAL_PROGRAM_EXE"]
p = subprocess.Popen(launchcmd, stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
self.outputThread = BashProcessThread(p.stdout.readline)
self.outputThread.start()
# wx.TextCtrl is used to make input/output
self.textctrl = wx.TextCtrl(self, style=wx.TE_PROCESS_ENTER|wx.TE_MULTILINE)我使用一个单独的线程来读取后台程序的stdout,并使用"wx.CallAfter“进行回调。
class BashProcessThread(threading.Thread):
def __init__(self, readlineFunc, textctrl):
threading.Thread.__init__(self)
self.readlineFunc = readlineFunc
def run(self):
while True:
line = self.readlineFunc()
wx.CallAfter(textctrl.AppendText(line))上面的代码打印子进程日志消息block-hanging-block (而不是自发地逐行打印),最糟糕的是,剩余的5-6行日志消息无法及时打印,直到用户发送下一个输入。
从我以前的帖子中,我了解到有pty和pexpect,这可能会使子进程认为它与伪tty交互。但是应该如何使用pexpect,特别是考虑到后台进程是一个长期的、独立运行的任务?
例如,如果我使用
child=pexpect.spawn(launchcmd)如何获得子流程的输出和输入,以便使用wx.TextCtrl打印输出,并使用wx.TextCtrl将用户输入转发给子流程?
发布于 2010-11-18 05:22:16
你有没有尝试过这样的东西:
child = pexpect.spawn(launchcmd)
while True:
try:
child.expect('\n')
print(child.before)
except pexpect.EOF:
break发布于 2014-06-12 00:41:04
我发现这两种方法可以很好地获得实时输出。
如果您不想使用该选项进行用户交互,例如在后台进程中:
child = pexpect.spawn(launchcmd)
child.logfile = sys.stdout
child.expect(pexpect.EOF)
child.close()如果您没有使用后台进程,并且希望能够与程序交互(如果它提示您的话)。这里发生的情况是,您进入交互模式,pexpect直接写入屏幕。当程序到达末尾时,它会抛出一个OSError。
child = pexpect.spawn(launchcmd)
try:
child.interact()
except OSError:
pass
child.close() https://stackoverflow.com/questions/4208820
复制相似问题