从内核到应用层:Linux缓冲机制与语言缓冲区的协同解析
系列文章目录
文章目录
- 系列文章目录
- 前言
- 一、缓冲区
- 1.1 示例1
- 1.2 缓冲区的概念
- 二、缓冲区刷新方案
- 三、缓冲区的作用及存储
前言
上篇我们介绍了,文件的重定向操作以及文件描述符的概念,今天我们再来学习一个和文件相关的知识-----------用户缓冲区。
在操作系统中,缓冲区是实现高效资源管理的关键进制,缓冲区可以帮助用户、系统暂存读取及写入数据,规避了用户频繁的I/O操作,可以很好的提高系统的性能和用户的体验。
一、缓冲区
由于我们对缓冲区接触的比较少,所以在讲解这部分知识时,我们会引入大量的代码示例,后面我们会对这些示例及结果逐一分析。
1.1 示例1
下列函数均向标准输出打印
1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 int main()5 {6 char *fstr="hello fwrite\n";7 char *wstr="hello witer\n";8 //c函数9 printf("hello printf\n");10 fprintf(stdout,"hello fprintf\n");11 fwrite(fstr,1,strlen(fstr),stdout); 12 //系统调用接口 13 write(1,wstr,strlen(wstr)); 14 return 0; 15 }
执行结果1:

将输出重定向至log1.txt
./myfile >log1.txt
执行结果2:

到现在执行结果都是我们可以接受的,不要着急继续向下看。
1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 int main()5 {6 char *fstr="hello fwrite\n";7 char *wstr="hello witer\n";8 //c函数9 printf("hello printf\n");10 fprintf(stdout,"hello fprintf\n");11 fwrite(fstr,1,strlen(fstr),stdout);12 //系统调用接口13 write(1,wstr,strlen(wstr));14 fork(); 15 return 0; 16 }
我们在文件末尾处创建了一个子进程,重复上面实验:
执行结果3:

将文件重定向输入到log2.txt
./myfile >log2.txt
执行结果4:

通过和前三次执行结果对比,我们可以看到向文件log2.txt打印的结果,库函数打印了两次,系统调用接口只打印了一次,通过对比结果2和结果4,我们可以知道一定是fork()函数产生的影响,那么为什么fork()没有对结果3产影响呢?带着这两问题我们继续往下看。
1.2 缓冲区的概念
我们接着来看下面这两个示例:
1 #include<stdio.h> 2 #include<string.h> 3 #include<unistd.h> 4 int main() 5 { 6 char *fstr="hello fwrite\n"; 7 char *wstr="hello witer\n"; 8 //c函数 9 printf("hello printf\n"); 10 fprintf(stdout,"hello fprintf\n"); 11 fwrite(fstr,1,strlen(fstr),stdout); 12 //系统调用接口13 write(1,wstr,strlen(wstr)); 14 //fork();15 close(1);16 return 0; 17 }
当执行完上面四个调用后我们使用close()函数关闭文件描述符1的文件。

此时并没有对程序执行结果造成影响,下面我们将\n全部去掉,继续执行程序。
1 #include<stdio.h>2 #include<string.h>3 #include<unistd.h>4 int main()5 {6 char *fstr="hello fwrite";7 char *wstr="hello witer";8 //c函数9 printf("hello printf");10 fprintf(stdout,"hello fprintf"); 11 fwrite(fstr,1,strlen(fstr),stdout);12 //系统调用接口13 write(1,wstr,strlen(wstr));14 //fork();15 close(1);16 return 0;17 }

可以看到此时只有系统调用接口成功将内容打印了出来,这又是怎么回事呢,相信大家早在学习C语言时,就听说过缓冲区,下面我们就来慢慢的回答上面一系列问题。

结合下面的解释看这个图,一定要仔细看,精华全在图上!!!!!
首先我们要清楚的一点是,printf/fprintf/fwrite全部是封装的系统调用write。在我们的内核中,进程会拥有对于的task_struct结构体,这个结构体对象包含一个文件结构体指针(上篇我们讲了,这里我们认为此时它指向显示器文件的file对象),通过这个文件对象可以找到内核缓冲区,所以的输入、输出,都需要经过这个缓冲区才能到达对应的磁盘中(包含硬件设备),当我们在执行C语言函数时,结果并不会直接打印在屏幕上,而是先存入C语言的缓存区,这一点通过上面的示例也能感受到,当程序执行到合适的时间,就会调用系统接口write,write通过文件描述符找到对应的文件对象,然后才能将c语言缓冲区的内容输出到内核缓冲区,当数据到达内核缓冲区,符合条件,就会被刷新到显示器上(磁盘),这个条件我们后面会介绍。
当程序执行系统调用write时,它会根据我们给他提供的文件描述符,找到对应的文件对象,直接将内容输出到内核缓冲区。有了这些概念,我们来分析上面代码。

当我们执行的程序执行c函数时,它会先将内容存入C语言的缓冲区,但程序执行系统调用时,他是将内容直接刷新到了系统缓冲区,程序继续向下执行close(1)显示器文件被关闭,此时c函数调用系统调用write想要将处在C语言缓冲区的数据输出道系统缓冲区,但是此时write已经无法找到显示器结构体对象了,素以无法实现,最后程序结束,系统缓冲区被刷新到显示器,结果表现为只有系统调用打印成功。到了这里我们算是回答了一个问题,那么为什么打印数据后加\n,就可以输出成功呢?要回答这个问题我们就要来谈一谈缓冲区刷新方案了。
二、缓冲区刷新方案
在这里我们只谈C语言的缓冲区刷新方案,我们将这种语言及的缓冲区称为用户及缓冲区(每个语言都会提供)。
缓冲区刷新方案主要有三种:
- 无缓冲-------直接刷新
- 行缓冲--------不刷新,直到碰见
\n(一般为向显示器打印时采用) - 全缓冲----------缓冲区满了,才刷新(一般为向文件打印时采用)
此外当程序执行结束后也会进行刷新。
现在我们可以来回答为什么,这里不受文件关闭的影响了。

当程序执行C函数时,会先将数据存入用户及缓冲区,但用户及缓冲区判断数据存在\n就会立即调用write将数据刷新到系统的缓冲区(此时文件还没有关闭)。
下面我们来回答这个问题

为什么我们对程序进行重载后,C函数的结果打印了两次。

当执行这个程序时,我们对他它重定向到文件,此时缓冲区刷新方案由之前的行缓冲变为全缓冲,所以c函数的执行结果会被存储在用户级缓冲区,而write的执行结果则会直接存入系统缓冲区,此时创建子进程,程序结束时,父进程要调用write将用户级缓冲区数据刷新到系统缓冲区上(这个行为会将用户及缓冲区数据清空),触发写时拷贝,子进程结束后也会将数据刷新,这时就有两份数据打印到了文件中。
不知道大家有没有注意到,我们上面例子的结果打印顺序,也出现了变化,刚刚的这个逻辑同样能解释这个问题,到了这里我们算是将问题都解决了
三、缓冲区的作用及存储
提高用户效率
在我们调用C函数向显示器或文件写入数据时,若没有缓冲区存在,其底层就会不断的去调用write函数,执行效率较低。
配合格式化
我们学习的printf/fprintf等函数,都是格式化输出函数(如使用%d格式化数据)但是在操作系统中并没有整形、浮点型等概念,在向显示器或文件打印时统一被作为字符输出,所以用户级缓冲区的作用就是将数据格式化处理后,再交有系统接口。

用户级缓冲区存储位置
用户缓冲区实际是被定义再FILE结构体中的。
相关文章:
从内核到应用层:Linux缓冲机制与语言缓冲区的协同解析
系列文章目录 文章目录 系列文章目录前言一、缓冲区1.1 示例11.2 缓冲区的概念 二、缓冲区刷新方案三、缓冲区的作用及存储 前言 上篇我们介绍了,文件的重定向操作以及文件描述符的概念,今天我们再来学习一个和文件相关的知识-----------用户缓冲区。 在…...
【AI News | 20250403】每日AI进展
AI Repos 1、llm-server-docs 项目提供了一份基于Debian系统的本地语言模型服务器搭建指南,适用于Linux初学者。教程涵盖驱动安装、GPU功耗设置、自动登录配置及开机自启脚本部署等关键步骤,支持Ollama/vLLM等多种OpenAI兼容方案。方案设计强调四大原则…...
深入理解SQL中的<>运算符:不等于的灵活运用
在SQL的世界里,数据的筛选与查询是最常见的操作之一。在编写查询语句时,比较运算符是我们不可忽视的工具,其中,<> 运算符作为 不等于 的代表,起着至关重要的作用。它不仅能够帮助我们筛选出符合特定条件的数据&a…...
单网卡上绑定多个虚拟IP(AI回答)
单网卡绑定多个虚拟IP的实现方法 一、Linux系统配置方案 1. 手动绑定少量IP地址(适用于CentOS/RHEL) 步骤1:进入网络配置目录 cd /etc/sysconfig/network-scripts/步骤2:复制并重命名网卡配置文件 cp ifcfg-eth0 i…...
数据清洗的具体内容
(一)ETL介绍 “ETL,是英文Extract-Transform-Load的缩写,用来描述将数据从来源端经过抽取(Extract)、转换(Transform)、加载(Load)至目的端的过程。ETL一词较…...
小家电等电子设备快充方案,XSP15支持全协议和支持MCU与电脑传输数据
随着USB-C的普及,市面上消费者PD充电器越来越多,如何让小家电等电子产品也能够支持PD协议快充呢?就需要加入一颗汇铭达XSP15取电协议芯片,这颗芯片不仅能支持取电,还能通过串口读取充电器支持的最大输出功率和支持外部…...
手动实现一个迷你Llama:手动实现Llama模型
进阶的 LLM Llama模型教学一、库导入二、实现 ModelArgs 参数类构建Transformer 模型参数解释 三、实现均方根归一化(RMSNorm,LayerNorm 的一种变体)层定义与原理RMSNorm 公式与 LayerNorm 的对比RMSNorm 的优点RMSNorm 的实现RMSNorm 的关键…...
缺页异常导致的iowait打印出相关文件的绝对路径
一、背景 在之前的博客 增加等IO状态的唤醒堆栈打印及缺页异常导致iowait分析-CSDN博客 里,我们进一步优化了D状态和等IO状态的事件的堆栈打印,补充了唤醒堆栈打印,也分析了一种比较典型的缺页异常filemap_fault导致的iowait的情况。 在这篇…...
记录学习的第十七天
今天对昨天下午的洛谷蓝桥杯模拟赛和今天早上的力扣周赛进行复盘。 昨天的蓝桥杯模拟赛,硬坐了4个小时,只会做前面的三道入门题。😥而且第一道填空题竟然还算错了。其他的五道题我都没啥思路了,实在难受啊! Q1:这道题硬…...
全面解析 Mybatis 与 Mybatis-Plus:深入原理、实践案例与高级特性对比
全面解析 Mybatis 与 Mybatis-Plus:深入原理、实践案例与高级特性对比 🚀 前言一、基础介绍 ✨1. Mybatis 简介 🔍2. Mybatis-Plus 简介 ⚡ 二、核心区别与高级特性对比 🔎1. 开发模式与配置管理2. 功能丰富度与扩展性3. 自动填充…...
Ubuntu 22.04 一键部署openManus
openManus 前言 OpenManus-RL,这是一个专注于基于强化学习(RL,例如 GRPO)的方法来优化大语言模型(LLM)智能体的开源项目,由来自UIUC 和 OpenManus 的研究人员合作开发。 前提要求 安装deepseek docker方式安装 ,windows 方式安装,Linux安装方式...
lib-zo,C语言另一个协程库,dns协程化, gethostbyname
lib-zo,C语言另一个协程库,dns协程化, gethostbyname 另一个 C 协程库 https://blog.csdn.net/eli960/article/details/146802313 本协程库 支持 DNS查询 协程化. 禁用所有 UDP 协程化 zvar_coroutine_disable_udp 1;禁用 53 端口的UDP 协程化 zvar_coroutine_disable_ud…...
强化学习_Paper_1988_Learning to predict by the methods of temporal differences
paper Link: sci-hub: Learning to predict by the methods of temporal differences 1. 摘要 论文介绍了时间差分方法(TD 方法),这是一种用于预测问题的增量学习方法。TD 方法通过比较连续时间步的预测值之间的差异来调整模型,…...
虚拟电商-话费充值业务(六)话费充值业务回调补偿
一、话费充值回调业务补偿 业务需求:供应商对接下单成功后充吧系统将订单状态更改为:等待确认中,此时等待供应商系统进行回调,当供应商系统回调时说明供应商充值成功,供应商回调充吧系统将充吧的订单改为充值成功&…...
Apache httpclient okhttp
学习链接 okhttp github okhttp官方使用文档 SpringBoot 整合okHttp okhttp3用法 Java中常用的HTTP客户端库:OkHttp和HttpClient(包含请求示例代码) 深入浅出 OkHttp 源码解析及应用实践 httpcomponents-client github apache httpclie…...
SQL Server 2022 读写分离问题整合
跟着热点整理一下遇到过的SQL Server的问题,这篇来聊聊读写分离遇到的和听说过的问题。 一、读写分离实现方法 1. 原生高可用方案 1.1 Always On 可用性组(推荐方案) 配置步骤: -- 1. 启用Always On功能 USE [master] GO ALT…...
Docker部署Blinko:打造你的个性化AI笔记助手与随时随地访问
文章目录 前言1. Docker Compose一键安装2. 简单使用演示3. 安装cpolar内网穿透4. 配置公网地址5. 配置固定公网地址 前言 嘿,小伙伴们,是不是觉得市面上那些单调乏味的笔记应用让人提不起劲?今天,我要给大家安利一个超炫酷的开源…...
Python Cookbook-5.2 不区分大小写对字符串列表排序
任务 你想对一个字符串列表排序,并忽略掉大小写信息。举个例子,你想要小写的a排在大写的 B 前面。默认的情况下,字符串比较是大小写敏感的(比如所有的大写字符排在小写字符之前)。 解决方案 采用 decorate-sort-undecorate(DSU)用法既快又…...
安全业务的manus时代即将到来
“(人)把业务流程任务化,把任务工具化,再把工具服务化,剩下的交给智能体。” 一、自动化与智能化浪潮下的安全业务变革 近期,笔者着迷于模型上下文协议(Model Context Protocol,简称MCP),这项技术所带来的变革性力量令人惊叹。在对多个技术案例进行实践的过程中,笔者…...
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析
程序化广告行业(55/89):DMP与DSP对接及数据统计原理剖析 大家好呀!在数字化营销的大趋势下,程序化广告已经成为众多企业实现精准营销的关键手段。上一篇博客我们一起学习了程序化广告中的人群标签和Look Alike原理等知…...
【文献研究】铝对热冲压加热过程中锌氧化的影响
在热冲压过程中,镀锌铁板和镀锌板等镀锌钢板表面发生Zn氧化。为了阐明镀锌层中的Al对Zn氧化的影响,本研究研究了镀锌钢板上添加和不添加Al时形成的ZnO量。发现添加铝后ZnO量减少。对添加铝的镀锌钢板的显微组织分析表明,添加的Al在热冲压后Zn…...
Win11本地从零开始部署dify全流程
1.安装wsl和打开Hyper-V功能(前置准备) 这个是为了支持我们的Docker Desktop运行。 1.1.安装wsl 使用管理员身份运行命令行。 如果显示 “无法与服务器建立连接就执行“,表示没有安装wsl,如果更新成功,那就不用执行…...
从代码学习深度学习 - RNN PyTorch版
文章目录 前言一、数据预处理二、辅助训练工具函数三、绘图工具函数四、模型定义五、模型训练与预测六、实例化模型并训练训练结果可视化总结前言 循环神经网络(RNN)是深度学习中处理序列数据的重要模型,尤其在自然语言处理和时间序列分析中有着广泛应用。本篇博客将通过一…...
【HTB】Windwos-easy-Legacy靶机渗透
靶机介绍,一台很简单的WIndows靶机入门 知识点 msfconsole利用 SMB历史漏洞利用 WIndows命令使用,type查看命令 目录标题 一、信息收集二、边界突破三、权限提升 一、信息收集 靶机ip:10.10.10.4攻击机ip:10.10.16.26 扫描TC…...
蓝桥杯真题———k倍区间
题目如下 代码如下 记录余数 cnt[0] 1 的初始化是为了处理 空前缀和 说明...
LeetCode 891 -- 贡献度思想
题目描述 子序列宽度之和 思路 ref 代码 相似题 子数组范围和 acwing...
无人机等非合作目标公开数据集2025.4.3
一.无人机遥感数据概述 1.1 定义与特点 在遥感技术的不断发展中,无人机遥感数据作为一种新兴的数据源,正逐渐崭露头角。它是通过无人驾驶飞行器(UAV)搭载各种传感器获取的地理空间信息,具有 覆盖范围大、综合精度高、…...
机器视觉--python基础语法
Python基础语法 1. Python标识符 在 Python 里,标识符由字母、数字、下划线组成。 在 Python 中,所有标识符可以包括英文、数字以及下划线(_),但不能以数字开头。 Python 中的标识符是区分大小写的。 以下划线开头的标识符是有特殊意义的…...
司南评测集社区 3 月上新一览!
司南评测集社区 CompassHub 作为司南评测体系的重要组成部分,旨在打创新性的基准测试资源导航社区,提供丰富、及时、专业的评测集信息,帮助研究人员和行业人士快速搜索和使用评测集。 2025 年 3 月,司南评测集社区新收录了一批评…...
TrollStore(巨魔商店)介绍及操作手册
TrollStore(巨魔商店)介绍及操作手册 一、TrollStore 简介 TrollStore 是一款针对 iOS 设备开发的第三方应用安装工具,它允许用户在不越狱设备的情况下,安装和使用未经过苹果官方 App Store 审核的应用程序。该工具利用了 iOS 系…...
