惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

S
Security Archives - TechRepublic
C
Cyber Attacks, Cyber Crime and Cyber Security
P
Proofpoint News Feed
Cisco Talos Blog
Cisco Talos Blog
L
Lohrmann on Cybersecurity
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
C
CERT Recently Published Vulnerability Notes
S
Secure Thoughts
H
Hacker News: Front Page
I
Intezer
Cyberwarzone
Cyberwarzone
T
Tor Project blog
The Last Watchdog
The Last Watchdog
Google DeepMind News
Google DeepMind News
T
Threatpost
T
Tenable Blog
NISL@THU
NISL@THU
AWS News Blog
AWS News Blog
阮一峰的网络日志
阮一峰的网络日志
T
Troy Hunt's Blog
E
Exploit-DB.com RSS Feed
V
Visual Studio Blog
W
WeLiveSecurity
腾讯CDC
The GitHub Blog
The GitHub Blog
T
The Exploit Database - CXSecurity.com
Engineering at Meta
Engineering at Meta
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
V2EX - 技术
A
Arctic Wolf
N
Netflix TechBlog - Medium
S
Securelist
WordPress大学
WordPress大学
Schneier on Security
Schneier on Security
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Vercel News
Vercel News
Recent Commits to openclaw:main
Recent Commits to openclaw:main
AI
AI
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
B
Blog
Apple Machine Learning Research
Apple Machine Learning Research
Help Net Security
Help Net Security
Google Online Security Blog
Google Online Security Blog
C
CXSECURITY Database RSS Feed - CXSecurity.com
G
Google Developers Blog
小众软件
小众软件
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Cloudbric
Cloudbric
P
Palo Alto Networks Blog

Unix

mv 命令文件夹后面加斜杠真的没有意义吗? Plesk 镜像制作(脚本) 怎么写 Mac 下的脚本? 会有人觉得unix系的命令行工具好用的吗,相比gnu的来说 V7/x86
请教下关于 IO 缓冲的一点疑问 - V2EX
yezheyu · 2023-10-30 · via Unix

最近在看《 unix 系统编程手册》和《 unix 环境高级编程》 看到 IO 缓冲区这块有点疑问,书上好多地方有提到缓冲区,但书上也没细说是内核缓冲区还是用户缓冲区 翻一下网上的帖子,发现也是如此。

我按照个人理解画了下面几幅图,大家帮我看下我理解的对吗?

read 函数:每次调用都执行一次 read 系统调用,没有缓存

fread 函数:

  • 当 fopen 打开文件时会先在用户空间为其建立一个缓冲区,用于减少系统调用。
  • 第一次 fread 5 个字节时,实际先使用 read 系统调用读取 2k 数据,但只返回给 fread 5 个字节。
  • 第二次 fread 5 个字节时,只是从用户缓冲区接着再读 5 个字节返回给 fread ,并未调用 read 系统调用。
  • 当用户缓冲区中 2k 数据被消费完,会自动进行预读,从输入缓冲区再 read 2k 数据为下次 fread 做准备

write 函数:每次调用都会执行一次 write 系统调用,没有缓存

fwrite 函数:

  • 当 fopen 打开文件时会先在用户空间为其建立一个缓冲区(假设是行缓冲模式),用于合并系统调用。
  • 第一次 fwrite 5 个未含有换行符的字节时,只是先把这个 5 个 bytes 放入用户缓冲区,并未触发 write 系统调用。
  • 第二次 fwrite 5 个含有换行符的字节时,也是把这个 5 个 bytes 放入用户缓冲区,但因为含有换行符,触发了 write 系统调用,把用户缓冲区的数据拷贝到输出缓冲区,再交给 DMA 保存到磁盘

我上面描述的对吗?

输入输出缓冲区是位于内核空间吗?

fopen 返回的 FILE 结构体是包含着用户缓冲区是吗?

如果 fopen 以读写方式打开文件,那是不是会在用户空间同时建立两个缓冲区,一个用于读,一个用于写?

fopen 打开文件返回的对象称之为 stream ,stream 是个啥?是不是其特点就是带有缓冲区,可以用于缓冲 IO ,合并系统调用?

如果使用 setvbuf 把 fread 中的用户缓冲区改为行缓冲模式,那第一次 read 时是不是只从输入缓冲区读取一行数据而不是 2k ?

test.txt 内容如下
ab
cd


FILE *file = fopen("test.txt", "r+");
char buf_cache[512];
setvbuf(file, buf_cache, _IOLBF, 512);
char c;
sleep(5);
fread(&c, 1, 1, file);
fread(&c, 1, 1, file);
fread(&c, 1, 1, file);
fread(&c, 1, 1, file);
fread(&c, 1, 1, file);
fclose(file);

那以上代码我用 strace 追踪为啥还是只调用了一次 read 系统调用呢?按理说不应该是因为有两行数据执行两次 read 吗?