这与我的另一篇文章有关wx.TextCtrl(或底层 GTK+)的多线程问题 https://stackoverflow.com/questions/4183404/multithreading-problem-with-wx-textctrl-or-underlying-gtk,在从主线程调用 GUI 交互进行纠正后,我发现它再次涉及管道块缓冲问题。那么如何从 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))
上面的代码块挂块地打印出子进程日志消息(而不是自发地逐行打印),最糟糕的是剩余的 5-6 行日志消息无法及时打印,直到用户发送下一个输入。
从我的旧帖子中,我了解到有 pty 和 pexpect,这可能使子进程认为它正在与伪 tty 交互。但是pexpect应该如何使用,特别是考虑到后台进程是长期的、独立运行的任务呢?
例如,如果我使用
child=pexpect.spawn(launchcmd)
如何获取子进程的输出和输入,以便我可以使用 wx.TextCtrl 打印输出,并使用 wx.TextCtrl 将用户输入转发到子进程?