2015-06-30 32 views
4

我正在写一个使用使用asyncio子进程时可以设置管道的缓冲区大小吗?

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

环绕另一个Python程序相当复杂的脚本 - 我不能永久地修改或以其他方式包括直接 - 捕捉要记录它的标准输出/犯错。包装的Python脚本不使用-u(无缓冲)选项,因此包装程序倾向于登录大缓冲区块。如果这是常规的子进程.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 

我认为他们的陷阱是有很好的理由,所以我不知道是否有一些其他的方式,我可以影响运输缓冲。

回答

1

我第一次向自己证明,这是一个真正的管道缓冲问题,将-u添加到包装程序的shebang行中。我不能依靠这个解决方案,因为这样的改变最终会被OS更新所破坏。

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

  • 的包装程序是管道的父程序,所以它控制它的子计划的环境。
  • 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'}) 

这完美地工作,并归功于我的好朋友和技术大师。