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

Getting a BlockingIOError when printing or writting to stdout

当我从一个需要终端处于“原始”模式的程序写入 tty 时,我在网络“BlockingIOError”中得到的记录很少而且很少出现。

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

检查 在 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, fcntl.F_SETFL, self.flags_save)

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

import terminedia as TM

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

(尽管在使用 terminedia 时应该使用“屏幕”class 而不是已经包装好的 TM.print