当前位置: 首页 > 面试题库 >

在C或Python中使用popen绕过子进程输出的缓冲

晋西岭
2023-03-14
问题内容

我有一个关于popen(及所有相关功能)的一般问题,适用于所有操作系统,当我编写python脚本或一些c代码并从控制台(win或linux)运行生成的可执行文件时,我可以立即看到输出从过程。但是,如果我运行与派生进程相同的可执行文件,并将其stdout重定向到管道中,则输出会在某个位置缓冲,通常最多4096字节,然后再将其写入父进程可以读取的管道中。

以下python脚本将生成1024字节的块的输出

import os, sys, time

if __name__ == "__main__":
     dye = '@'*1024
     for i in range (0,8):
        print dye
        time.sleep(1)

以下python脚本将执行上一个脚本,并在到达管道时逐字节读取输出

import os, sys, subprocess, time, thread

if __name__ == "__main__":
    execArgs = ["c:\\python25\\python.exe", "C:\\Scripts\\PythonScratch\\byte_stream.py"]

    p = subprocess.Popen(execArgs, bufsize=0, stdout=subprocess.PIPE)
    while p.returncode == None:
        data = p.stdout.read(1)
        sys.stdout.write(data)
        p.poll()

调整操作系统的路径。在此配置中运行时,尽管popen命令的缓冲区大小设置为0(无论如何都是默认值),输出将不会出现在1024的块中,而是4096的块中。有人可以告诉我如何更改此行为吗?有什么办法可以迫使操作系统以与从控制台运行时相同的方式来处理分叉进程的输出?没有缓冲?


问题答案:

通常,标准C运行时库(或多或少代表每个系统上的每个程序运行;-)检测stdout是否为终端;如果没有,它将缓冲输出(与未缓冲的输出相比,这将是巨大的效率优势)。

如果您在控制正在编写的程序,则可以(建议另一个答案)连续刷新stdout,或者(如果可行的话,更优雅些)尝试强制stdout不被缓冲,例如通过使用带有-u命令行标志的Python运行:

-u     : unbuffered binary stdout and stderr (also PYTHONUNBUFFERED=x)
         see man page for details on internal buffering relating to '-u'

(手册页添加的内容是提及stdin和二进制模式的问题)。

如果您不能或不想触摸正在编写的程序,-u或者正在读取的程序上的类似内容不太可能有所帮助(最重要的缓冲是发生在编写者标准程序上的缓冲,而不是发生在编写程序标准上的缓冲)。读者的标准输入)。另一种方法是欺骗作者,使其相信它是通过pty标准库模块或更高级别的第三方pexpect模块(或者,对于Windows而言,是其端口)正在写入终端(即使实际上它正在写入另一个程序!)。wexpect)。



 类似资料:
  • 问题内容: 我对使用时如何搜索可执行文件感到困惑。如果给子进程提供了绝对路径,那么它就可以工作,但是我正在尝试使用相对路径。我发现,如果设置环境变量PYTHONPATH,则可以从该路径中获取导入的模块,并且PYTHONPATH在其中,但似乎对的行为没有帮助。我也尝试编辑将PYTHONPATH添加到的文件,就像这样 并验证了在以交互方式,与ipython或通过从命令行运行脚本启动python时,PY

  • 问题内容: 我正在尝试运行可执行文件并使用;捕获其输出;但是,我似乎并没有获得全部输出。 手动打开时,它比原始exe文件少打印两行。 我尝试了一种具有相同结果的替代方法: 任何人都可以帮助我获取exe的完整数据吗? 正如塞巴斯蒂安的要求: 原始exe文件最后几行o / p: -Gdd:通用计数(1-1000) -Cdd:切割起始于(0-99)-Edd:切割终止于(1-100) 请在下面选择流文件编

  • 我试图使用popen启动一个子进程,该子进程一个接一个地调用两个命令(带有多个参数)。第二个命令依赖于第一个命令的运行,因此我希望使用一个子进程同时运行这两个命令,而不是生成两个进程并等待第一个。 但是我遇到了一些问题,因为我不知道如何给出两个命令输入,或者如何将命令作为一个对象分开。 另外,如果可能的话,我会尽量避免将shell设置为true。 这基本上就是我要做的:

  • 问题内容: 我在命令行中执行的操作: 我想用python做什么: 问题答案: 更新:不鼓励使用,尽管在Python 3中仍然可用。 用途 如果你确实要使用子流程,请使用以下解决方案(大部分内容来自子流程的文档): OTOH,你可以完全避免系统调用:

  • 问题内容: 我在Ubuntu上使用,并且有一个Python 2.7脚本可以打印并说出一条消息: 产生所需的声音,但由于一些错误(,没有套接字连接)而使外壳混乱,因此我无法轻松读取之前打印的内容。退出代码为0。 不幸的是,没有记录的选项可以关闭它的冗长性,因此我正在寻找一种方法,仅在视觉上使其静音并保持打开的外壳干净以进行进一步的交互。 我怎样才能做到这一点? 问题答案: 将输出重定向到DEVNUL

  • 问题内容: 我相信在环境稍有修改的情况下运行外部命令是很常见的情况。这就是我倾向于这样做的方式: 我感觉到有更好的办法了。看起来还好吗? 问题答案: 我认为如果你不打算为当前过程修改会更好: