Linux学习笔记(十二)--用户缓冲区

用户缓冲区

在Linux操作系统中,用户缓冲区是应用程序在用户空间内维护的一块内存区域,用于临时存储待写入文件或网络的数据,或从文件/网络读取的数据。它的主要目的是减少系统调用次数,提高I/O效率。

用户缓冲区的类型

先来一段代码研究一下

复制代码
#include<stdio.h>
#include<string.h>

int main()
{
    const char *msg0="hello printf\n";
    const char *msg1="hello fwrite\n";
    const char *msg2="hello write\n";

    printf("%s", msg0);
    fwrite(msg1, strlen(msg0), 1, stdout);
    write(1, msg2, strlen(msg2));

    fork();

    return 0;
}

当代码运行之后结果是

复制代码
hello printf
hello fwrite
hello write

但当我们对进程实现输出重定向(./hello > file)时,结果变成

复制代码
hello write
hello printf
hello fwrite
hello printf
hello fwrite

两次结果不一致,这是因为printf和fwrite函数都输出了两次,write只输出了一次。这与fork有关,C库函数的缓冲机制与系统调用存在显著差异。库函数如printffwrite等,在输出到文件时采用全缓冲,而输出到显示器时通常采用行缓冲,当发生重定向时,缓冲方式会发生改变。相比之下,系统调用write没有内置缓冲机制,会立即执行写入操作。这种差异在实际编程中会带来重要的行为差异。例如,当程序调用fork()创建子进程时,由于写时拷贝机制的存在,父子进程会共享缓冲区的数据,这可能导致输出结果与预期不符。

所以用户缓冲区的类型有三种,分别是:

(1)全缓冲:缓冲区填满时刷新(如普通文件)。
(2)行缓冲:遇到换行符\n时刷新(如终端标准输出stdout)。
(3)无缓冲:立即输出(如标准错误stderr)。

用户缓冲区和内核缓冲区的关系:

用户缓冲区与内核缓冲区(如页缓存Page Cache)是独立但协作的两层:用户缓冲区位于进程地址空间,由应用程序或标准库管理。而内核缓冲区位于内核空间,用于缓存磁盘数据或网络数据,减少物理I/O。

数据流示例:

复制代码
应用程序数据 → 用户缓冲区 → write()系统调用 → 内核缓冲区 → 磁盘/网络

用户缓冲区与内核缓冲区区别:

用户缓冲区刷新(如fflush())仅将数据复制到内核缓冲区,不保证落盘。内核缓冲区由内核管理,通过fsync()或定时刷新(通常30秒)写入磁盘。

缓冲区的控制方法:

(1) 标准库缓冲控制

setvbuf():设置缓冲区模式(全缓冲/行缓冲/无缓冲)及自定义缓冲区。

fflush():强制刷新指定文件的用户缓冲区到内核。

setbuf()/setbuffer():简化版缓冲区设置。

(2) 系统调用绕开用户缓冲区

使用read()/write()等系统调用时,数据直接在内核和用户空间传递,不经过标准库缓冲区(但仍有内核缓冲区参与)。

(3) 强制落盘

fsync(fd):确保内核缓冲区数据写入物理磁盘。

fdatasync(fd):类似fsync,但只刷新数据部分(不更新元数据)。

用户缓冲区的核心作用

减少系统调用开销 :每次系统调用(如read()/write())都需要从用户态切换到内核态,涉及上下文保存、权限检查等开销。通过缓冲区累积数据后批量操作,可大幅降低切换频率。(示例 :若每次写1字节,调用write()100次需100次系统调用;而用1KB缓冲区累积数据后写入,仅需1次系统调用。)

适配不同I/O粒度:应用程序的数据处理单位(如逐字符)可能与内核或磁盘的块大小(如4KB)不匹配。缓冲区作为中间层,可累积小数据到合适粒度再提交。

优化硬件访问:磁盘或网络设备更适合大块数据传输。缓冲区积累足够数据后,内核可合并多次小写入为单次大块I/O,提升设备利用率。

相关推荐
Coder个人博客3 小时前
Linux6.19-ARM64 mm mmu子模块深入分析
大数据·linux·车载系统·系统架构·系统安全·鸿蒙系统
羊群智妍5 小时前
2026 AI搜索流量密码:免费GEO监测工具,优化效果看得见
笔记·百度·微信·facebook·新浪微博
Doro再努力5 小时前
Vim 快速上手实操手册:从入门到生产环境实战
linux·编辑器·vim
wypywyp6 小时前
8. ubuntu 虚拟机 linux 服务器 TCP/IP 概念辨析
linux·服务器·ubuntu
阿蒙Amon6 小时前
TypeScript学习-第10章:模块与命名空间
学习·ubuntu·typescript
AI绘画哇哒哒6 小时前
【干货收藏】深度解析AI Agent框架:设计原理+主流选型+项目实操,一站式学习指南
人工智能·学习·ai·程序员·大模型·产品经理·转行
Doro再努力6 小时前
【Linux操作系统10】Makefile深度解析:从依赖推导到有效编译
android·linux·运维·服务器·编辑器·vim
senijusene6 小时前
Linux软件编程:IO编程,标准IO(1)
linux·运维·服务器
忧郁的橙子.6 小时前
02-本地部署Ollama、Python
linux·运维·服务器
醇氧6 小时前
【linux】查看发行版信息
linux·运维·服务器