我只是好奇应该满足哪些条件自动刷新stdout缓冲区.
首先,我很困惑这个伪代码不会在每次迭代时打印输出:
while (1) {
printf("Any text");
sleep(1);
}
Run Code Online (Sandbox Code Playgroud)
但如果我添加换行符,它会.
经过几次实验,我发现在我的机器上stdout缓冲区被刷新:
第一个条件是完全清楚的 - 当缓冲区已满时,应该刷新它.第二个也是合理的.但为什么换行符导致潮红?其他隐含的条件是什么?
自动刷新stdout缓冲区的规则是实现定义的(ID).当流是无缓冲,完全缓冲或行缓冲时,它是ID .
当流未缓冲时,字符应尽快从源或目的地出现.否则,可以将字符作为块累积并发送到主机环境或从主机环境发送.
当流被完全缓冲时,当填充缓冲区时,字符将作为块传输到主机环境或从主机环境传输.
当流被行缓冲时,当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输.此外,当填充缓冲区,在无缓冲流上请求输入时,或者在需要从主机环境传输字符的行缓冲流上请求输入时,字符旨在作为块传输到主机环境. .
对这些特性的支持是实现定义的,...C11dr§7.21.33
我只是好奇应该满足哪些条件自动刷新stdout缓冲区.
如果代码想确保输出肯定是刷新的,请使用fflush().可以自动刷新流的其他条件是实现定义的.
每当输出换行符时,应刷新行缓冲的输出流。
每当尝试从任何行缓冲输入流进行读取时,实现都可以(但不要求)刷新所有行缓冲输出流。
默认情况下不允许实现完全缓冲流,除非可以确定它们不与“交互式设备”关联。因此,当 stdin/stdout 是终端时,它们不能完全缓冲,只能行缓冲(或无缓冲)。
如果仅在输出到终端时需要刷新,则可以假设写入换行符会导致刷新。否则,您应该fflush在需要刷新的地方显式调用。
请参阅的手册页setbuf(3)。默认情况下,stdout设置为行缓冲模式。
printf()及其变体使用缓冲输出,并委托给write(). 因此,该缓冲由 的 C 库实现控制printf,缓冲区和缓冲区设置位于FILE结构体中。
还值得注意的是 unix 手册页第 3 节和第 2 节之间的区别。第 2 部分由函数调用组成,这些函数调用直接与操作系统对话,并执行纯用户程序无法执行的操作。第 3 部分由用户可以自己重现的函数调用组成,这些函数调用通常委托给第 2 部分调用。第 2 部分函数包含允许 C 程序与外界交互并执行 I/O 的低级“魔法”。第 3 节函数可以为第 2 节函数提供更方便的接口。
printf、scanf、getchar、fputs和其他FILE *函数都是第 3 节函数,它们委托给write()和read(),而 和 是第 2 节函数。read()并且write()不缓冲。 printf()与结构中的缓冲区交互FILE,有时决定通过 发送该缓冲区的内容write()。