首页  >  文章  >  后端开发  >  为什么当使用 `for line in iter(process.stdout.readline, \'\')` 从 C 程序读取输出时,我的 Python `subprocess` 挂起?

为什么当使用 `for line in iter(process.stdout.readline, \'\')` 从 C 程序读取输出时,我的 Python `subprocess` 挂起?

Mary-Kate Olsen
Mary-Kate Olsen原创
2024-11-18 05:23:02662浏览

Why Does My Python `subprocess` Hang When Reading Output from a C Program Using `for line in iter(process.stdout.readline, '')`?

Python 子进程因“for line in iter”而挂起

在这种情况下,Python 脚本旨在执行 C 程序并接收它的输出。然而,脚本挂在了“for line in iter(process.stdout.readline, '')”行。

缓冲问题

问题产生于缓冲问题。在 C 程序中,当输出通过管道传送时,stdout 通常是块缓冲的。这意味着输出会被缓冲,直到写入一定量或遇到换行符为止。

在 C 程序中,while 循环的每次迭代都会打印“2000”并休眠一秒钟。由于没有打印换行符,因此输出被缓冲。

For Line in Iter Issue

在 Python 中, subprocess.stdout.readline() 读取子进程的 stdout处理并返回一行。 “for line in iter()”循环迭代 readline() 返回的行。

但是,由于 C 程序的输出由于缓冲而没有被刷新,因此此时没有要读取的行Python 脚本进入循环的位置。因此,脚本会在这一行无限期地等待。

解决方案

修复 C 程序中的缓冲

  • setvbuf():C程序可以使用setvbuf() 强制标准输出进行行缓冲。这将确保打印后立即刷新每一行。
setvbuf(stdout, (char *) NULL, _IOLBF, 0);
  • stdbuf 实用程序:stdbuf 实用程序可用于包装 C 程序并更改其缓冲
stdbuf -oL ./main

伪 TTY

  • Pty 模块:pty 模块可用于创建一个伪 TTY,欺骗 C 程序认为它正在交互运行。在此模式下,默认情况下输出将采用行缓冲。
import pty
master_fd, slave_fd = pty.openpty()
process = Popen("./main", stdin=slave_fd, stdout=slave_fd, stderr=STDOUT,
                bufsize=0, close_fds=True)
  • pexpect 库:pexpect 库提供了用于使用 ptys 的更高级别接口。
import pexpect
child = pexpect.spawn("./main")
for line in child:
    print line

通过应用这些解决方案之一,缓冲问题将得到解决,允许 Python 脚本按预期读取 C 程序的输出。

以上是为什么当使用 `for line in iter(process.stdout.readline, \'\')` 从 C 程序读取输出时,我的 Python `subprocess` 挂起?的详细内容。更多信息请关注PHP中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn