sud*_*03r 73 language-agnostic io buffering
我了解到,默认情况下,程序中的I/O是缓冲的,即它们从临时存储器提供给请求程序.我知道缓冲可以提高IO性能(可能通过减少系统调用).我已经看到了禁用缓冲的示例,例如setvbuf在C中.两种模式之间有什么区别?何时应该使用另一种模式?
pax*_*blo 111
无论何时希望确保在继续之前写入输出,都需要无缓冲输出.一个例子是C运行时库下的标准错误 - 默认情况下,这通常是无缓冲的.由于错误(希望)很少发生,因此您希望立即了解错误.另一方面,标准输出被缓冲,因为它假设将有更多的数据通过它.
另一个例子是日志库.如果您的日志消息保存在进程的缓冲区中,并且您的进程转储核心,那么很可能永远不会写入输出.
此外,不仅系统调用最小化,而且磁盘I/O也是如此.假设一个程序一次读取一个字节的文件.使用无缓冲输入,你会为每个字节输出(相对非常慢)磁盘,即使它可能必须在整个块中读取(磁盘硬件本身可能有缓冲区,但你仍然要去磁盘控制器)这将比内存访问慢.
通过缓冲,立即将整个块读入缓冲区,然后从(内存中,速度极快)缓冲区传送单个字节.
请记住,缓冲可以采用多种形式,例如以下示例:
+-------------------+-------------------+
| Process A | Process B |
+-------------------+-------------------+
| C runtime library | C runtime library | C RTL buffers
+-------------------+-------------------+
| OS caches | Operating system buffers
+---------------------------------------+
| Disk controller hardware cache | Disk hardware buffers
+---------------------------------------+
| Disk |
+---------------------------------------+
Run Code Online (Sandbox Code Playgroud)
Aar*_*ron 30
当你已经准备好写入磁盘的大量字节序列时,你想要无缓冲的输出,并且想要避免在中间的第二个缓冲区中额外复制.
缓冲输出流将写入结果累积到中间缓冲区,仅在累积(或flush()请求)足够数据时才将其发送到OS文件系统.这减少了文件系统调用的数量.由于文件系统调用在大多数平台上memcpy都很昂贵(与short相比),因此在执行大量小写操作时,缓冲输出是一个净赢.当您已经有大缓冲区要发送时,无缓冲输出通常会更好 - 复制到中间缓冲区不会进一步减少OS调用次数,并引入了额外的工作.
无缓冲输出与确保数据到达磁盘无关 ; 该功能由flush()缓冲和非缓冲流提供,并在其上工作.无缓冲的IO写入不保证数据已到达物理磁盘 - 操作系统文件系统可以无限期地保留数据副本,如果需要,则永远不会将其写入磁盘.只需要在调用时将其提交到磁盘flush().(请注意,close()将flush()代表您致电).