Linux之文件--缓冲区和c封装
📅 2026/7/28 23:27:36
👁️ 次浏览
缓冲区在哪里read操作系统把内核缓冲区的数据拷贝到你传入的用户内存buf 如果内核缓冲区没有需要的数据 → OS 发起硬件请求从磁盘加载数据进入内核缓冲区再拷贝给应用。write把应用buf的数据拷贝进内核缓冲区函数返回后续内核再异步写到磁盘。操作表 一组函数指针数组跳转表存储这个文件 / 硬件对应的read、write、open、close、llseek等底层实现地址。//内核伪代码 struct file_operations { //读写偏移 loff_t (*llseek) (struct file *, loff_t, int); //对应系统调用 read() ssize_t (*read) (struct file *, char __user *, size_t, loff_t *); //对应系统调用 write() ssize_t (*write) (struct file *, const char __user *, size_t, loff_t *); //打开文件 int (*open) (struct inode *, struct file *); //关闭文件 int (*release) (struct inode *, struct file *); //还有 ioctl、poll、mmap…… };用户层永远只调用统一 APIread(fd)/write(fd)不需要区分底层是磁盘文件、键盘、显示器、网卡、串口。 内核收到系统调用后根据 fd 找到struct file取出里面的f_op操作表调用操作表里对应的函数指针缓冲区在内核空间内核缓冲区图中间区域内核缓冲区、磁盘、read()/write()系统调用、struct file归属内核空间操作系统维护所有进程共享内核缓存资源接口系统调用read(int fd, buf, size) / write()数据流向write 流程应用 → 用户缓冲区 → write 系统调用 → 内核缓冲区 →延迟刷新磁盘read 流程磁盘 → 内核缓冲区 → read 系统调用拷贝 → 用户缓冲区 → 应用程序变量重点调用write()绝不直接写磁盘write 只是把数据拷贝到内核缓冲区操作系统会在合适时机内核线程 pdflush把缓冲区数据刷入磁盘这种机制叫延迟写。为什么要有缓冲区系统调用是有成本的,我们要减少系统调用的次数new malloc底层都是会调用系统调用,但是你在申请的时候给你的是虚拟地址空间,当你真正开始用的时候在区物理内存里面给你申请比如在stl里面vector需要扩容的时候,一般采用2倍,这样也有利于减少系统调用的次数为了减少系统调用,c,c就登场了用户级缓冲区归属用户空间由 C 标准库libc维护接口fopen/fgets/fputs/fprintf/fread/fwrite这些标准 IO 函数意义减少系统调用次数系统调用read/write会发生用户态 ↔ 内核态切换开销大。 程序不会调用一次write写 1 个字节而是先把数据攒在用户缓冲区缓冲区满 / 主动刷新时才调用一次write系统调用进入内核。两条数据流路线路线 A标准库 IO带用户缓冲区 fputs/fprintf应用内存变量 →FILE 用户缓冲区→ 缓冲区刷新 →write()系统调用 →内核缓冲区→ 操作系统异步刷入磁盘路线 B原生系统调用无用户缓冲区 read/write应用内存 buffer → 直接通过read/write在内核缓冲区、程序内存之间拷贝接下来我们看下面三个现象eg1Linux 规则最小可用文件描述符分配进程启动默认fd0 (标准输入)、fd1 (标准输出 stdout)、fd2 (标准错误 stderr)close(1)释放 fd1随后open()打开文件优先拿到最小空闲 fd也就是 1最终fd 1 指向 log.txtprintf底层往stdoutfd1输出所以内容本该写入 log.txt。说明printf数据放入 stdout 缓冲区尚未 writeclose(fd)→关闭文件描述符 fd1缓冲区数据还躺在内存里但是通往文件的 fd 已经被关掉等到程序退出库函数尝试刷新缓冲区、调用 write (fd1) → fd1 已经关闭系统调用失败缓冲区数据直接丢失文件没有写入任何内容log.txt为空文件当我们为他添加fflush,时又重新把hello world写入log.txt文件eg2运行效果等待 1 秒后输出hello运行效果等待 1 秒无任何输出printf(hello)不带换行符\n程序输出到终端stdout 是行缓冲模式。 行缓冲规则只有遇到\n、主动fflush、进程正常库层退出才刷新缓冲区单纯字符串无换行数据停留在C 库用户缓冲区不会调用 write 系统调用。exit会刷新语言级缓冲,二_exit则不会,导致缓冲区内容丢失eg3标准 IO 库函数C 库带用户缓冲区printf / fprintf(stdout) / fputs数据先存入进程用户态 stdio 缓冲区不一定立刻调用write系统调用。系统调用无用户缓冲区write(fd,buf,len)直接发起内核调用数据直达内核缓冲区不存在用户缓冲区滞留。前置缓冲规则输出到终端交互式 shellstdout 行缓冲遇见\n自动刷新缓冲区输出到普通文件重定向 aaaastdout 全缓冲\n不会触发刷新数据停留在用户缓冲区解释现象1../buffer.exe直接终端运行行缓冲 每条标准 IO 带\n触发缓冲区刷新依次打印 4 行无重复。2../buffer.exe aaaa重定向到文件全缓冲\n不再刷新程序退出时exit()统一刷新缓冲区。 顺序write 直接输出随后程序退出一次性输出缓冲区内 3 条标准 IO 内容。解释现象forkfork()创建子进程时采用写时复制COW父进程整个用户地址空间完整复制一份给子进程。stdio 缓冲区位于用户地址空间会被一并拷贝分支 1终端运行行缓冲 标准 IO 函数内部\n触发刷新fork 执行前缓冲区已经清空。 fork 时父子进程缓冲区都是空的后续没有重复输出。分支 2重定向文件全缓冲\n不会刷新缓冲区执行fork()那一刻 父进程的 stdout 缓冲区还存放着hello printf\nhello printf\nhello fprintf\nhello fputs\nfork 复制地址空间 →子进程拿到一份一模一样的缓冲区副本。父子进程是独立进程父进程退出刷新自身缓冲区输出一组标准 IO 内容子进程退出刷新自己复制得来的缓冲区再次输出同一组内容而write()是系统调用没有用户缓冲区在 fork 之前就已经完成内核输出只会打印一次。内核缓冲区两种刷新方式主动强制落盘fsync () /fdatasync ()系统调用强制把内核缓冲区数据立即写入磁盘硬件等待磁盘 IO 完成才返回。fsync(fd)刷新文件数据 文件元信息大小、修改时间等fdatasync(fd)只刷新文件内容不强制同步元信息性能略高操作系统异步自动刷新内核后台守护进程pdflush/flusher定时扫描在系统空闲、内存不足时自动把 Page Cache 数据刷到磁盘无需程序干预。
1. 项目概述:为什么CI流水线必须嵌入镜像安全扫描?最近在梳理团队的CI/CD流水线,发现一个挺普遍但容易被忽视的问题:我们花了大量精力做代码扫描、单元测试,但最终打包出来的容器镜像,其内部依赖的安全性却…
📅 2026/7/28 23:27:36
破局 CTF:从密码学迷雾到逆向工程深处在 CTF(Capture The Flag)的赛场上,Web 和 Misc 方向往往因为上手快、反馈直接而成为新手的“舒适区”。然而,真正决定比赛上限的,往往是那些让人望而生畏的 Crypto&am…
📅 2026/7/28 23:27:36
为什么 Kali Linux 是渗透测试的“瑞士军刀”在网络安全的学习路径中,工具的选择往往决定了实战的效率。对于初学者而言,面对琳琅满目的安全软件,最容易陷入“收藏党”的误区——下载了一堆工具却不知从何下手。Kali Linux 之所以成为行业标准…
📅 2026/7/28 23:27:36
如果你正在使用 Fly.io 部署应用,或者关注云原生和 AI 基础设施的最新动态,那么最近的一条消息值得你停下来仔细看看:Fly.io 的创始人兼 CEO Kurt Mackey 即将卸任,而这家以轻量、快速的边缘部署著称的平台,正在将战略…
📅 2026/7/29 2:44:46
1. 项目概述:从“找不到设备”到“精准对话”在玩转Maqueen这类基于micro:bit的智能小车平台时,很多朋友都会遇到一个看似简单却让人抓狂的问题:我明明按照教程接好了传感器或扩展模块,为什么程序就是读不到数据?代码逻…
📅 2026/7/29 2:44:46
1. 项目概述:自考学习中的AIGC工具选择困境作为一名自考辅导老师,我见证了太多学生在论文写作环节的挣扎。最近两年,随着AIGC技术的爆发式发展,学生们开始面临新的挑战——如何在合理利用AI辅助工具的同时,确保学术诚信…
📅 2026/7/29 2:44:46
1. 接口与匿名内部类:Java开发中的黄金搭档在Java开发中,接口和匿名内部类就像是一对默契十足的搭档,它们共同构成了Java面向对象编程中灵活性和扩展性的基石。作为一名有十年Java开发经验的工程师,我发现这两个概念在实际项目中无…
📅 2026/7/29 2:44:46
1. 项目缘起:当“融合”、“长片段”与“突变”同时出现在分子克隆的日常里,我们常常会接到一些听起来就让人心头一紧的任务。比如,构建一个“表达载体”,这本身是基础操作。但如果这个载体需要同时承载“融合基因”、“长片段基因…
📅 2026/7/29 2:44:46
做生信分析,最烦的是什么?不是代码报错。是重复劳动。你手里可能有几十个GEO数据集。每个都要下载。每个都要预处理。还要手动选差异基因。手都点麻了。我见过太多同行,还在用浏览器一个个点。效率低得吓人。还容易出错。今天,咱们聊聊怎么解放双手。核心就一个词:自动化。…
📅 2026/7/29 2:43:49
解密Seq的核心功能:如何利用Pipeline实现高效基因组数据处理 【免费下载链接】seq A high-performance, Pythonic language for bioinformatics 项目地址: https://gitcode.com/gh_mirrors/se/seq
Seq作为一款高性能的生物信息学专用语言,其Pipel…
📅 2026/7/29 0:00:00
Flask-Blogging插件开发指南:打造属于你的个性化博客功能 【免费下载链接】Flask-Blogging A Markdown Based Python Blog Engine as a Flask Extension. 项目地址: https://gitcode.com/gh_mirrors/fl/Flask-Blogging
Flask-Blogging是一个基于Markdown的Py…
📅 2026/7/29 0:00:00
近日,国际专注开放式技术研发的声学品牌Nank南卡,正式官宣实力艺人曾舜晞担任品牌代言人。消息一经发出便轰动全网。为什么耳机品牌不选择流量明星、老牌歌手?而且是选择曾舜晞?让我们一起来探索一下!比起短期的流量&a…
📅 2026/7/29 0:01:00
更多请点击:
https://codechina.net
第一章:AI帮助理解数学概念 人工智能正以前所未有的方式重塑数学学习的路径。通过自然语言处理与符号计算的深度融合,AI不仅能解析抽象定义,还能将定理、证明和几何直觉转化为可交互、可验证的…
📅 2026/7/29 1:14:44
1. 项目背景与核心价值去年参与的一个短剧项目让我深刻体会到传统创作流程的痛点:编剧团队花了三周打磨剧本,角色设计反复修改了七版,最后成片时又因为演员档期问题不得不临时调整分镜。这种低效的创作模式在快节奏的内容行业越来越难以为继。…
📅 2026/7/29 1:14:44
remix-i18next TypeScript类型安全实践:确保翻译键与类型定义同步 【免费下载链接】remix-i18next The easiest way to translate your React Router framework mode apps 项目地址: https://gitcode.com/gh_mirrors/re/remix-i18next
在开发多语言应用时&am…
📅 2026/7/29 1:14:46
目录
第一步:选对模板,省心一半
第二步:打开扫码点餐功能
开启功能按钮
桌台管理与桌码生成
第三步:个性化设计,打造品牌感
调整点餐页面
设置点餐规则 你还在让顾客站着排队点餐吗?2025年ÿ…
📅 2026/7/28 7:13:45
在业务中快速构建一个能理解私有文档、准确回答专业问题的智能助手,是很多开发团队面临的共同挑战。传统方案往往需要从零开始搭建复杂的 RAG(检索增强生成)系统,涉及文档解析、向量化、检索、大模型调用等多个环节,整…
📅 2026/7/28 17:14:18
FAE放射组学分析工具:医学影像特征探索的完整解决方案 【免费下载链接】FAE FeAture Explorer 项目地址: https://gitcode.com/gh_mirrors/fae/FAE
你是否曾经面对海量医学影像数据感到无从下手?想要从CT、MRI等影像中提取有价值的定量特征&#…
📅 2026/7/28 5:13:40