python 中的 os.read(0,) 与 sys.stdin.buffer.read()

Jay*_*Jay 4 python stdin

我遇到了picotui库,很想知道它是如何工作的。

我在这里(第 147 行)看到它使用:

os.read(0,32)
Run Code Online (Sandbox Code Playgroud)

谷歌说 0 代表标准输入,但从标准输入读取的公认答案是通过

sys.stdin.buffer.read()
Run Code Online (Sandbox Code Playgroud)

我想知道两者之间有什么区别。哪个更快?哪个版本更便携?

Cha*_*ffy 8

Usingos.read(0, 32)无缓冲读取,直接调用操作系统级别的系统调用并仅读取非常特定数量的数据(并保证单个调用不会读取更多数据)。有时候-比如,如果你将要越区切换出你的标准输入到一个不同的程序,让 读取挂起数据的其余部分-特别需要这一点。

sys.stdin.buffer.read()是一个缓冲读取(并且,在不指定长度的情况下,读取尽可能多)。缓冲读取可能会读取您立即要求的更多数据(即使它只返回请求的数量,将其余部分保留在缓冲区中以用于处理未来的请求),以减少进行的系统调用数量,从而与读取大量数据时降低上下文切换开销(特别是,当您进行大量短读时,缓冲会减少用户空间和操作系统内核之间的往返次数)。

其中哪一个合适在很大程度上取决于实现和运行时环境细节,并且询问哪个适合给定场景的问题需要包含更多细节以免过于宽泛。重要的是你不要混合它们;在缓冲读取之后执行非缓冲读取可能会产生不可预测的结果,因为无法知道操作系统已经读取了多少数据来填充读取缓冲区中尚未使用的部分。

  • 你的两个问题的答案是,按顺序是,不是。第一个 `0` 是 FD 编号,因此将 `0` 传递给 `sys.stdin.read` 是没有意义的;`sys.stdin` 本身的标识指定了 FD。此外,`sys.stdin.read` 不能保证是一个无缓冲的系统调用,而 `os.read()` *是*。 (2认同)
  • `os` 是低级系统调用接口所在的地方,并且允许跨平台不兼容(即使 `read` 在实践中,AFAIK,不应该是;它在 UNIX 中已经存在了足够长的时间,已经变得非常普遍) . `sys` 是高级接口所在的位置。 (2认同)