I am trying to learn the libuv
api and wrote the following test:
#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;
}
When run it, no output is displayed until the program finishes running, and then all the output is displayed at once. If I uncomment the fflush
line it works as expected, writing every 2 seconds.
Can someone please explain this to me? Why is stdout
not flushed after the newline, as is explained here and in other places? Why do I need tomanually flush it?
For some reason, your system is deciding that your stdout is not interactive. Are you doing some strange redirect of stdout or doing something weird with your terminal? You should be able to override using setbuf or you can use stderr instead of stdout.
Stream buffering is implementation-defined.
Per 7.21.3 Files, paragraph 3 of the C Standard:
The type of buffering is dependent on your implementation, and your implementation apparently isn't line-buffering in your example.
There is no strict requirement, that
stdout
is line buffered. It may be fully buffered as well (or not buffered at all), in which case\n
does not trigger to flush the stream.C11 (N1570) 7.21.3/7 Files:
C11 (N1570) 5.1.2.3/7 Program execution:
You could try to force specific type of buffering by
setvbuf
standard function. For instance, to set line buffering forstdout
, you may try with:where
buff
is declared as character array ofsize
elements (e.g. 1024).Note that
setvbuf
has to be called before any other I/O operation, that is performed to the stream.