微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

打印或写入标准输出时出现 BlockingIOError

如何解决打印或写入标准输出时出现 BlockingIOError

当我需要终端处于“原始”模式的程序写入 tty 时,我在网络“BlockingIOError”中得到了很少的记录和较少的存在。

在 Unix (Linux,Mac) 中将终端切换到 raw 是让行显示方法 不打印换行符,更重要的是,阅读输入的任何内容 无需等待 <enter> 键。

检查 https://stackoverflow.com/a/6599441/108205获取在 Python 中执行此操作的可靠方法

但是,当将数据打印到原始终端时,我会不时地让我的程序以 BlockingIOError 异常终止。

(我什至建立了一个重试机制来解决它,但有时它根本无法解决)。

异常出现在 github 上的一些问题中,没有关于如何修复它的断言。 用我的项目触发它的方法是:

import terminedia as TM

with TM.keyboard:  # enables the use of TM.inkey() for realtime keyboard reading
    print("*" * 100_000)

(您可以pip install terminedia尝试)

解决方法

这个片段,创建一个上下文管理器,它暂时将 tty 切换回“正常”阻塞模式,包装具有大量输出的部分为我解决了这个问题:

import fcntl
import os
...

class UnblockTTY:

    def __enter__(self):
        self.fd = sys.stdin.fileno()
        self.flags_save = fcntl.fcntl(self.fd,fcntl.F_GETFL)
        flags = self.flags_save & ~os.O_NONBLOCK
        fcntl.fcntl(self.fd,fcntl.F_SETFL,flags)

    def __exit__(self,*args):
        fcntl.fcntl(self.fd,self.flags_save)

为了完整起见,问题中的代码片段将被修复:

import terminedia as TM

with TM.keyboard:  
    with TM.terminal.UnblockTTY():
        print("*" * 100_000)

(虽然在使用 terminedia 时应该使用“Screen”类而不是已经包装好的 TM.print

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。