【问题标题】:PyInstaller unbuffered stdioPyInstaller 无缓冲标准输出
【发布时间】:2018-09-12 19:44:49
【问题描述】:

问题

Docker 映像大小通常应尽可能小。使用像standard python 图像这样的成熟环境通常会在严重臃肿的图像中安装所有依赖项。将 python 打包成独立的可执行文件(例如使用 pyinstaller)是减少图像大小和整体复杂性的完美方法。

环境python3.6pyinstaller==3.4

出现的问题是,python 使用默认缓冲的 stdio。这可以通过使用python -u ... 运行 python 脚本来缓解。但是在使用 pyinstaller 时变得无法访问。

根据docs,应该可以向生成的可执行文件添加运行时选项,例如uvW ...。但不幸的是,实际上它似乎不起作用。 vW 都可以正常工作,但 u 似乎完全被忽略了。

下面的sn-p显示用法:

...
exe = EXE(...
          [('u', None, 'OPTION')],
          name="myapp",
          ...)
...

这个标志仍然有效吗?由于其他人工作 - 它是否在没有通知或更新文档的情况下被删除?

是否有其他方法可以禁用 stdio 的缓冲(使用 pyinstaller 或在外部),无需修改 python 代码,如so

为什么需要这样做?

在运行 docker swarm 服务时要避免缓冲 IO。为了使可执行文件正确地实时登录到 docker 守护进程,有必要附加一个 shell。但是,将 tty shell 附加到 swarm 任务上使得处理日志变得更加复杂,甚至不可能。

【问题讨论】:

    标签: python docker pyinstaller stdio


    【解决方案1】:

    至少它在 Windows 上已损坏(请参阅 issue on github),并且不在 docs 中。

    【讨论】:

      【解决方案2】:

      这个pull request 解决了这个问题。

      '-u' 选项将设置 Py_UnbufferedStdioFlag 标志以在 Python 库中启用无缓冲 stdio 模式。

      这个doc 展示了如何使用规范文件启用运行时选项。

      options = [ ('u', None, 'OPTION') ]
      a = Analysis( ...
              )
      ...
      exe = EXE(pyz,
        a.scripts,
        options,   <--- added line
        exclude_binaries=...
        )
      

      注意:

      这启用了 stdout 和 stderr 流的无缓冲二进制层 所有支持的 Python 版本,而无缓冲文本层需要 Python 3.7 或更高版本。

      【讨论】:

        猜你喜欢
        • 2013-11-28
        • 2013-10-27
        • 1970-01-01
        • 2014-12-07
        • 2016-10-25
        • 2011-05-03
        • 2010-12-06
        • 1970-01-01
        • 2012-05-02
        相关资源
        最近更新 更多