posts - 86,comments - 0,views - 11226

文件流缓冲区

每个进程都各自维护一个文件流表,和文件描述符表类似,并且这些文件流都有自己对应的缓冲区

缓冲区的设计就是为了减少磁盘io,加快io的速度

缓冲区模式

通过setvbuf或者setbuf两个函数设置缓冲区的模式

无缓冲区

就是禁用缓冲区的意思,这种模式下,就相当于直接调用write函数,不过在调用write之前可能还要处理一些格式化输出等问题,这是和直接调用write的一个小区别

行缓冲区

当标准输出(或者输入)定向到终端时,默认采用行缓冲模式,就是接收到换行符就刷新缓冲区

块缓冲区

当缓冲区的数据达到一个块的大小时,刷新缓冲区,重定向时,默认使用块缓冲区

全缓冲区

当数据填满缓冲区时,刷新缓冲区

总结对比

特性 无缓冲区(No Buffering) 行缓冲区(Line Buffering) 块缓冲区(Block Buffering) 全缓冲区(Full Buffering)
定义 数据不经过缓冲,直接写入目标设备 每当输入一行数据时,才进行输出 数据以块为单位进行缓冲,达到块大小后输出 数据在缓冲区中,直到填满后一次性输出
刷新时机 每次写入操作都立即刷新 每当遇到换行符时刷新 当缓冲区满或达到特定块大小时刷新 缓冲区满或显式调用刷新时才输出
内存使用 无额外内存开销 较少的内存开销 预定的块大小内存开销 较大的内存开销,通常是输出的总大小
性能 频繁I/O操作,性能较低 适合逐行处理,性能适中 减少I/O操作,提高性能 适合长时间不需要输出的场景,性能较高
适用场景 实时处理要求高的场景 交互式程序或逐行输出 大数据处理或文件写入 批处理或需要大量输出的场景
实时反馈 反馈及时 逐行反馈 反馈延迟,直到块大小达到 反馈延迟,直到缓冲区满

与fork和exit之间的交互

fork函数用于创建子进程,这样的话子进程会复制一份父进程的stdio流缓冲区

exit函数在调用_exit函数前,会刷新所有stdio流缓冲区

这两个配合起来,有时候就会发现有的输出打印了两份,这是因为缓冲区没有及时刷新的原因,有以下几种办法

  • 可以设置缓冲区模式
  • 使用fflush立即刷新
  • 父进程使用exit函数在程序结束后刷新,子进程使用_exit函数退出,该函数不刷新缓冲区

所以在有多进程的情况下使用stdio流,要注意缓冲区的模式,以及何时刷新缓冲区,避免出现意外情况

posted on   Dylaris  阅读(9)  评论(0编辑  收藏  举报
< 2025年2月 >
26 27 28 29 30 31 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 1
2 3 4 5 6 7 8

点击右上角即可分享
微信分享提示