为什么printf在调用后不刷新,除非格式字符串中有换行符?这是POSIX行为吗?如何让printf每次都立即刷新?
当前回答
这样做可能是为了提高效率,也因为如果有多个程序写入一个TTY,这样就不会让一行上的字符相互交错。所以如果程序A和B输出,你通常会得到:
program A output
program B output
program B output
program A output
program B output
这太糟糕了,但总比
proprogrgraam m AB ououtputputt
prproogrgram amB A ououtputtput
program B output
请注意,它甚至不保证在换行上刷新,因此如果刷新对您很重要,则应该显式刷新。
其他回答
默认情况下,stdout是行缓冲,stderr是无缓冲,文件是完全缓冲。
注意:Microsoft运行时库不支持行缓冲,因此printf(“将立即打印到终端”):
https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setvbuf
一般有2级缓冲-
1. 内核缓冲区缓存(使读/写更快)
2. I/O库中的缓冲(减少no。系统调用)
让我们以fprintf和write()为例。
When you call fprintf(), it doesn't wirte directly to the file. It first goes to stdio buffer in the program's memory. From there it is written to the kernel buffer cache by using write system call. So one way to skip I/O buffer is directly using write(). Other ways are by using setbuff(stream,NULL). This sets the buffering mode to no buffering and data is directly written to kernel buffer. To forcefully make the data to be shifted to kernel buffer, we can use "\n", which in case of default buffering mode of 'line buffering', will flush I/O buffer. Or we can use fflush(FILE *stream).
现在我们在内核缓冲区中。内核(/OS)希望最小化磁盘访问时间,因此它只读取/写入磁盘块。因此,当发出read()时(这是一个系统调用,可以直接或通过fscanf()调用),内核从磁盘读取磁盘块并将其存储在缓冲区中。之后,数据从这里复制到用户空间。
类似地,从I/O缓冲区接收到的fprintf()数据由内核写入磁盘。这使得read() write()更快。
现在要强制内核启动write(),之后的数据传输由硬件控制器控制,也有一些方法。我们可以在写调用期间使用O_SYNC或类似的标志。或者我们可以使用其他函数,如fsync(),fdatasync(),sync(),让内核在内核缓冲区中有数据时立即启动写操作。
这样做可能是为了提高效率,也因为如果有多个程序写入一个TTY,这样就不会让一行上的字符相互交错。所以如果程序A和B输出,你通常会得到:
program A output
program B output
program B output
program A output
program B output
这太糟糕了,但总比
proprogrgraam m AB ououtputputt
prproogrgram amB A ououtputtput
program B output
请注意,它甚至不保证在换行上刷新,因此如果刷新对您很重要,则应该显式刷新。
Stdout是缓冲的,因此只在打印换行符后输出。
要获得立即输出,可以:
打印到标准错误。 使stdout无缓冲。
推荐文章
- C多行宏:do/while(0) vs作用域块
- time_t最终的类型定义是什么?
- 我需要显式处理负数或零时,总和平方数字?
- 函数名周围的括号是什么意思?
- 用C语言创建自己的头文件
- 格式化IO函数(*printf / *scanf)中的转换说明符%i和%d之间的区别是什么?
- main()中的Return语句vs exit()
- 如果不是内存地址,C指针到底是什么?
- 我如何在Visual Studio中预处理后看到C/ c++源文件?
- 保护可执行文件不受逆向工程的影响?
- 从C语言的函数返回一个struct
- C99 'restrict'关键字的实际用法?
- 检查子字符串存在于C中的字符串中
- 从标准输入中捕获字符,而不需要等待按enter键
- 查找当前可执行文件的路径,不包含/proc/self/exe