subprocess.Popen 和缓冲进程输出

发布于 2024-10-17 01:44:10 字数 607 浏览 3 评论 0原文

从 python 代码内部,我想运行一个从标准输入获取参数的二进制程序。使用 subprocess 模块,这应该很简单:

import subprocess
command = [ 'my_program' ]
p = subprocess.Popen( command,  \
        stdin = subprocess.PIPE, stdout = subprocess.PIPE, \
        env={ "GFORTRAN_UNBUFFERED_ALL": "1"} )
p.stdin.write ( stdin_stuff )
while True:
  o = p.stdout.readline()
  if p.poll() != None: 
    break
  # Do something with stdout

现在,这会启动程序,但 python 脚本只是挂在那里。我知道这很可能是由于 gfortran (我用来编译 my_program 正在缓冲其 stdout 流。gfortran 允许使用 GFORTRAN_UNBUFFERED_ALL 环境变量,就像我所做的那样,以及在 fortran 代码中使用 FLUSH() 内在函数,但仍然没有运气:python 代码仍然挂起。

From inside python code, I want to run a binary program that gets its parameters from stdin. Using the subprocess module, this should be straightforward:

import subprocess
command = [ 'my_program' ]
p = subprocess.Popen( command,  \
        stdin = subprocess.PIPE, stdout = subprocess.PIPE, \
        env={ "GFORTRAN_UNBUFFERED_ALL": "1"} )
p.stdin.write ( stdin_stuff )
while True:
  o = p.stdout.readline()
  if p.poll() != None: 
    break
  # Do something with stdout

Now, this launches the program, but the python script just hangs there. I understand that this may well be due gfortran (which I use to compile my_program is buffering its stdout stream. gfortran allows one to use the GFORTRAN_UNBUFFERED_ALL environmental variable, as I have done, as well as using the FLUSH() intrinsic in the fortran code, but still no luck: the python code still hangs.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

温馨耳语 2024-10-24 01:44:10

使用 Popen.communicate() 将字符串发送到进程的 stdin,而不是手动写入。

stdoutdata, stderrdata = p.communicate(stdin_stuff)

You should have better luck using Popen.communicate() to send strings to the process' stdin rather than manually writing to it.

stdoutdata, stderrdata = p.communicate(stdin_stuff)
多彩岁月 2024-10-24 01:44:10

为了补充 Aphex 的答案,这里是 < a href="http://docs.python.org/library/subprocess.html" rel="nofollow noreferrer">文档:

警告

使用communicate()而不是.stdin.write.stdout.read.stderr.read > 避免由于任何其他操作系统管道缓冲区填满并阻塞子进程而导致死锁。

To complement Aphex's answer, here the relevant part of the documentation:

Warning

Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文