python - 打印或写入 stdout 时出现 BlockingIOError

标签 python posix nonblocking tty

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

在 Unix(Linux、Mac)中将终端切换为原始终端是显示行的方法 不打印换行符,更重要的是,读取输入的任何内容 无需等待 <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, fcntl.F_SETFL, self.flags_save)

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

import terminedia as TM

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

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

关于python - 打印或写入 stdout 时出现 BlockingIOError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67351928/

相关文章:

python - GNOME 桌面通知中缺少图像/图标

python - 非阻塞fifo

javascript - React - 如何从长时间运行的操作将正确的 prop 传递给子组件

javascript - setTimeout VS Web Worker - 何时使用什么?

Python正则表达式解析流

python - 一旦没有线程请求它,垃圾收集锁

python程序按元音计数排序

c - 如何打开临时文件并获取其文件名?

c - 如何在C中对缓冲区中的内容进行分区

objective-c - OSX 上的单调时钟