Python 子进程和标准输出 - 程序死锁

Python subprocess & stdout - program deadlocks

我有一个模拟程序,它通过 stdin 进行试验并向 stdout 提供输出

在 QProcess 中为 运行 执行 C++/Qt 程序效果很好。

[=35=下为运行做一个Python程序]linux 效果很好,使用:

p = subprocess.Popen(cmd,stdin=subprocess.PIPE,stdout=subprocess.PIPE)

并使用 p.stdin.writep.stdout.readlinep.wait

然而,在windows下,程序正常运行并通过stdin获取命令(这已经通过调试子进程验证),但 python 程序在任何 p.stdout.readlinep.wait 处死锁。如果去掉stdout=subprocess.PIPE参数,程序运行,输出显示在控制台上,不会发生死锁。

这听起来很熟悉 Python 文档中的警告:

Warning : This will deadlock when using stdout=PIPE and/or stderr=PIPE and the child process generates enough output to a pipe such that it blocks waiting for the OS pipe buffer to accept more data. Use communicate() to avoid that.

但是,我不能使用 communicate(),因为程序协议不是单个命令和单个输出,而是需要多个命令和回复。

有什么解决办法吗?

不确定,但看起来像是 缓冲 问题。在 Linux 上(在大多数 Unix 或类 Unix 上),文件或管道的输出在 OS 级别进行内部缓冲。这意味着在 write 调用之后,所有数据都被缓冲,但管道的另一端没有任何可用数据,直到内部缓冲区已满、数据被刷新或管道关闭。这就是 pty 被发明并且 不是 用管道对实现的原因之一。

换句话说,如果您需要使用以前的输出来知道应该使用管道输入什么,则无法驱动程序,除非该程序是通过在读取之前始终刷新其输出而专门为其量身定制的任何事物。它在真正的终端(tty 或 pty)上工作,因为在同一设备上进行任何读取之前,驱动程序会自动强制刷新输出。

但这不是您在问题中引用的文档中描述的同一个 dealock。