【问题标题】:Python subprocess & stdout - program deadlocksPython 子进程和标准输出 - 程序死锁
【发布时间】:2018-03-08 22:25:28
【问题描述】:

我有一个模拟程序,它通过标准输入进行试验并提供输出到标准输出

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

linux 下运行 Python 程序效果很好,使用:

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 文档中的警告:

警告:这将在使用 stdout=PIPE 和/或 stderr=PIPE 时出现死锁,并且子进程会向管道生成足够的输出 这样它会阻止等待操作系统管道缓冲区接受更多 数据。使用communicate() 来避免这种情况。

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

有什么解决办法吗?

【问题讨论】:

  • 您是否尝试过使用bufsize 增加缓冲区?它可能会有所帮助

标签: python process stdout stdin


【解决方案1】:

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

换句话说,不可能驱动一个程序,您需要使用先前的输出来知道您应该使用管道将什么作为输入作为输入,除非该程序已通过在读取任何内容之前始终刷新其输出而专门为其定制。它适用于真正的终端(tty 或 pty),因为驱动程序会在同一设备上进行任何读取之前自动强制刷新输出。

但它与您在问题中引用的文档中描述的解除锁不同。

【讨论】:

    猜你喜欢
    • 2012-04-26
    • 1970-01-01
    • 2017-12-26
    • 2011-08-29
    • 1970-01-01
    • 1970-01-01
    • 2012-05-28
    • 2021-02-06
    • 1970-01-01
    相关资源
    最近更新 更多