C 为什么是标准输出缓冲?
我正在尝试学习C 为什么是标准输出缓冲?,c,libuv,C,Libuv,我正在尝试学习libuvapi,并编写了以下测试: #include <stdio.h> #include <stdlib.h> #include <uv.h> void timer_cb(uv_timer_t* timer) { int* i = timer->data; --*i; if(*i == 0) { uv_timer_stop(timer); } printf("timer %d\n"
libuv
api,并编写了以下测试:
#include <stdio.h>
#include <stdlib.h>
#include <uv.h>
void timer_cb(uv_timer_t* timer) {
int* i = timer->data;
--*i;
if(*i == 0) {
uv_timer_stop(timer);
}
printf("timer %d\n", *i);
//fflush(stdout);
}
int main() {
uv_loop_t* loop = uv_default_loop();
uv_timer_t* timer = malloc(sizeof(uv_timer_t));
uv_timer_init(loop, timer);
int i = 5;
timer->data = &i;
uv_timer_start(timer, timer_cb, 1000, 2000);
uv_run(loop, UV_RUN_DEFAULT);
printf("Now quitting.\n");
uv_close(timer, 0);
uv_loop_close(loop);
return 0;
}
#包括
#包括
#包括
无效计时器\u cb(紫外线计时器\u t*计时器){
int*i=定时器->数据;
--*一,;
如果(*i==0){
紫外线定时器停止(定时器);
}
printf(“计时器%d\n”,*i);
//fflush(stdout);
}
int main(){
uv_loop_t*loop=uv_default_loop();
uv_timer_t*timer=malloc(sizeof(uv_timer_t));
uv_定时器_init(循环,定时器);
int i=5;
计时器->数据=&i;
紫外线定时器启动(定时器,定时器cb,1000,2000);
uv_运行(循环,uv_运行默认值);
printf(“正在退出。\n”);
uv_关闭(计时器,0);
uv_回路_闭合(回路);
返回0;
}
当运行它时,在程序完成运行之前不显示任何输出,然后立即显示所有输出。如果我取消注释fflush
行,它将按预期工作,每2秒写入一次
有人能给我解释一下吗?为什么在换行后,
stdout
没有像前面解释的那样在其他地方刷新?为什么我需要手动刷新它?流缓冲是实现定义的
根据7.21.3文件,第3段:
当一条溪流
无缓冲的字符旨在尽快从源位置或目标位置出现。否则字符
可累积并传输到主机或从主机传输
将环境视为块。当一条溪流
完全缓冲,当缓冲区填满时,字符将作为块传输到主机环境或从主机环境传输。当
溪流是
行缓冲,当新行出现时,字符将作为块传输到主机环境或从主机环境传输
遇到字符。此外,字符的目的是
当缓冲区被激活时,作为块传输到主机环境
在非缓冲流上请求输入时,或
在需要的行缓冲流上请求输入
从主机传输字符
环境对这些特性的支持是
已定义实施,并可能通过setbuf
和
setvbuf
函数
缓冲的类型取决于您的实现,在您的示例中,您的实现显然不是行缓冲。没有严格的要求,
stdout
是行缓冲的。它也可以被完全缓冲(或者根本不被缓冲),在这种情况下,\n
不会触发刷新流
C11(N1570)7.21.3/7文件:
初始打开时,标准错误流没有完全缓冲;
标准输入和标准输出流在以下情况下完全缓冲:
并且仅当可以确定流不引用
交互式设备
C11(N1570)5.1.2.3/7程序执行:
交互设备的构成由实现定义
您可以尝试通过setvbuf
标准函数强制特定类型的缓冲。例如,要为标准输出设置行缓冲,您可以尝试:
setvbuf(stdout, buff, _IOLBF, size);
其中,buff
被声明为size
元素(例如1024)的字符数组
请注意,在对流执行任何其他I/O操作之前,必须先调用
setvbuf
。由于某些原因,您的系统决定您的stdout不是交互式的。你是在做一些奇怪的stdout重定向还是在用你的终端做一些奇怪的事情?您应该能够使用setbuf覆盖,或者可以使用stderr而不是stdout。“为什么stdout缓冲”-为什么不?这个答案可能对您有用:@AndrewHenle窗口,打开mingw64msys@Olaf我明白了(见最后我链接的答案)缓冲区在newline@baruch:您在标准中的什么地方找到的?我使用setvbuf(stdout,NULL,_IOLBF,0)将其设置为行缓冲代码>但它仍然不起作用。只有当我将其设置为无缓冲(\u IONBF
)时,才会执行此操作work@baruch:AFAIR,setvbuf
需要为其提供自备的缓冲区。否则,它将无法工作。我使用setvbuf(stdout,NULL,_IOLBF,0)将其设置为行缓冲代码>但它仍然不起作用。只有当我将它设置为无缓冲(\u IONBF
)时,它才会像该答案中的链接一样工作,在Windows上没有行缓冲。我想这就是问题所在,但这并不能回答这个问题。若要评论或要求作者澄清,请在其帖子下方留下评论。-我认为它包括两个答案:使用setvbuf或stderr。第三个答案只是暗示,用来解释为什么系统将stdout误认为是非交互式的。