请教下关于 IO 缓冲的一点疑问

2023-10-30 17:51:27 +08:00
 yezheyu

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

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

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

fread 函数:

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

fwrite 函数:

我上面描述的对吗?

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

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 吗?

705 次点击
所在节点   Unix
3 条回复
zeonluang
2023-10-30 18:01:56 +08:00
“如果 fopen 以读写方式打开文件,那是不是会在用户空间同时建立两个缓冲区,一个用于读,一个用于写?”
肯定是一个

“按理说不应该是因为有两行数据执行两次 read 吗?”
两行数据在同一个 page 里
yezheyu
2023-10-30 18:16:59 +08:00
@zeonluang 是不是对于文件来说,如果文件数据比较小,page 的优先级是高于行缓冲模式?
yezheyu
2023-10-31 10:54:39 +08:00
顶下帖

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/986797

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX