【发布时间】:2019-07-16 02:14:56
【问题描述】:
我正在尝试更深入地了解 C 和 stdio 中的缓冲是如何工作的,我发现了一些我觉得有趣的东西。我阅读了this 文章,但我想确认我的理解正确。
当我使用 fgets 时,将输入缓冲设置为 3 个字节 (stdbuf -i3) 并检查 strace,我看到读取以 3 个字符为一组发生,这是我所期望的:
read(0, "hel", 3) = 3
read(0, "lo\n", 3) = 3
...
如果我仍然使用stdbuf,但这次我使用read(2) 系统调用,它会一次读取全部内容(最多4096 个字节):
read(0, "hello\nworld!\n\n", 4096) = 14
所以它忽略了stdbuf 调用。
这让我彻底重新思考stdio 缓冲。 stdio 本质上是否维护自己的缓冲区,stdbuf -i3 是说从内核的主管道缓冲区一次读取 3 个字节?我认为执行stdbuf -i0 会使管道的容量以某种方式无法容纳超过一个字节(即write(2) 调用将在从将stdout 发送到进程的无缓冲stdin 的进程的1 个字节后阻塞) .
所以说有 2 个缓冲区位于实际管道缓冲区之上,进一步缓冲 stdout 和 stdin 是否正确?而setbuf 只控制这两个缓冲区,而不是修改有关内核管道缓冲区的任何属性。因此,将stdin 设置为n 字节缓冲区意味着它将在返回内核执行read 系统调用之前保留n 字节。
【问题讨论】: