【问题标题】:Is it possible to set the buffer size of pipes when using asyncio subprocesses?使用 asyncio 子进程时是否可以设置管道的缓冲区大小?
【发布时间】:2015-06-30 20:59:46
【问题描述】:

我正在编写一个相当复杂的脚本,正在使用

asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE)

包裹另一个 Python 程序——我无法永久修改或直接包含该程序——以捕获其 stdout/err 以进行日志记录。包装的 Python 脚本未使用 -u(无缓冲)选项,因此包装程序倾向于登录大缓冲块。如果这是常规的 subprocess.Popen 我可以通过 bufsize=1 来获得我想要的,即行缓冲。但是,如果我将它添加到 asyncio.create_subprocess_exec() 他们会专门为它捕获,我得到:

<snip>
  File "/usr/lib64/python3.4/asyncio/subprocess.py", line 193, in create_subprocess_exec
    stderr=stderr, **kwds)
  File "/usr/lib64/python3.4/asyncio/base_events.py", line 642, in subprocess_exec
    raise ValueError("bufsize must be 0")
ValueError: bufsize must be 0

我认为他们的陷阱是有充分理由的,所以我想知道是否有其他方法可以影响传输缓冲。

【问题讨论】:

    标签: python buffering


    【解决方案1】:

    我首先通过将-u 添加到包装程序的shebang 行来向自己证明这确实是一个管道缓冲问题。不过,我不能将其作为解决方案,因为这样的更改最终会被操作系统更新所破坏。

    虽然我能够以类似的方式解决该问题:

    • 包装程序是管道的父程序,因此它控制其子程序的环境。
    • Python 应该在其继承的环境中遵守 PYTHONUNBUFFERED=1
    • asyncio.create_subprocess_exec() 确实支持 env= 参数以及可以传递给 subprocess.Popen() 的大多数其他内容;可能有点记录不足,但查看代码会很明显。

    所以我把电话改为:

    asyncio.create_subprocess_exec(sub_cmd, *sub_cmd_args, stdout=PIPE, stderr=PIPE, env={'PYTHONUNBUFFERED': '1'})
    

    这非常有效,这要归功于我的好朋友和技术大师。

    【讨论】:

      猜你喜欢
      • 2011-07-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-19
      相关资源
      最近更新 更多