阻塞与非阻塞 I/O 缓冲?

Posted

技术标签:

【中文标题】阻塞与非阻塞 I/O 缓冲?【英文标题】:Blocked vs unblocked I/O buffering? 【发布时间】:2019-07-18 06:01:17 【问题描述】:

我正在阅读一些关于 z/OS 的 blocked IO 概念的信息。它指出:

阻塞 I/O 是对 ISO 标准的扩展。对于以块格式打开的文件,z/OS® XL C/C++ 一次读取和写入一个块。如果您尝试向块中写入的数据多于该块可以容纳的数据,则数据将被截断。对于阻塞的 I/O,z/OS XL C/C++ 只允许使用 fread() 和 fwrite() 来读取和写入文件。

然后说:

fflush() 函数对阻塞的 I/O 文件无效。

但是,在another 文章中,它说:

对于终端,因为 I/O 总是畅通的,所以行缓冲是 相当于完全缓冲。

对于记录 I/O 文件,缓冲是 仅对 z/OS UNIX 中的阻塞文件或记录 I/O 文件有意义 使用完全缓冲的文件系统。对于未阻塞的文件,缓冲区是 每次写入后已满,因此立即写入,离开 没有什么可冲洗的。对于被阻止的文件或完全缓冲的 UNIX 文件系统 文件,但是,缓冲区可以包含一个或多个记录 没有被刷新并且需要刷新操作才能进入 系统。

对于阻塞的 I/O 文件,缓冲总是没有意义的。

我对这一切感到非常困惑。如果 I/O 是畅通的,那么行缓冲如何等同于全缓冲?为什么刷新不会对块 I/O 产生影响?另外,阻塞的 I/O 导致缓冲总是没有意义是什么意思?任何关于阻塞和非阻塞 I/O 发生了什么以及它如何影响缓冲效果的直觉都将不胜感激。

【问题讨论】:

【参考方案1】:

我对您提供的内容的看法是,这是指 MVS 数据集的阻塞 I/O。这些将不同于存储在 Unix 系统服务 HFS / ZFS 中的文件。并且不同于终端 I/O。

我对这一切感到非常困惑。如果 I/O 未阻塞,将如何 行缓冲等价于全缓冲?

我认为您指的是对终端 I/O 的引用,它表明一行是一条记录并且与块大小相同,因此每条记录都是一个完整的数据块。也就是说,每个块有一条 LRECL = BLKSIZE == 1 条记录,因此它没有被缓冲,或者,缓冲区就是记录。

为什么刷新不会对块 I/O 产生影响?

如果每个块有多个记录,则 fflush 不会写入块,直到块已满。我怀疑这与平台上比 C 更早的 z/OS 中的 I/O 实现有关,因此他们做出了设计决定,在 I/O 的执行方式上不会导致不同语言的不同行为。

另外,阻塞的 I/O 导致缓冲总是没有意义是什么意思?

同样,z/OS 会写入完整的块,但文件中的最后一个块可能很短,因为它没有包含完整块的足够记录。

在 C 进入平台之前,z/OS 有很多历史,z/OS 竭尽全力提供一致性。

【讨论】:

以上是关于阻塞与非阻塞 I/O 缓冲?的主要内容,如果未能解决你的问题,请参考以下文章

操作系统-IO零拷贝

操作系统-IO零拷贝

操作系统-IO零拷贝

socket阻塞与非阻塞,同步与异步I/O模型

socket阻塞与非阻塞,同步与异步I/O模型

聊聊阻塞与非阻塞同步与异步I/O模型