I'm just curious which conditions should be satisfied to flush stdout buffer automatically.
First of all I was confused that this pseudo code doesn't print output every iteration:
while (1) {
printf("Any text");
sleep(1);
}
But if I add newline character it will.
After few experiments i found that on my machine stdout buffer is flushed:
The first condition is totally clear - when the buffer is full it should be flushed. The second one is also reasonable. But why newline character causes flushing? What are the others implicit conditions for this?
The buffer flush is used to transfer of computer data from one temporary storage area to computers permanent memory. If we change anything in some file, the changes we see on the screen are stored temporarily in a buffer. In C++, we can explicitly have flushed to force the buffer to be written.
Flushing output on a buffered stream means transmitting all accumulated characters to the file. There are many circumstances when buffered output on a stream is flushed automatically: When you try to do output and the output buffer is full. When the stream is closed.
So, what it basically comes down to is pretty simple: when you read from stdin , if anything has been written to stdout , but not flushed yet, it'll be flushed automatically before the system waits for input from stdin (unless you've done something like redirecting one or both to a file).
In C, file output is block buffered. Output to stdout is line buffered. The stderr device is unbuffered.
There are many circumstances when buffered output on a stream is flushed automatically:
stdout
is line buffered by default.
If you want to flush the buffered output at another time,You can call fflush.
Rules of automatic flushing stdout buffer is implementation-defined (ID). It is ID when the stream is unbuffered, fully buffered, or line buffered.
When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block.
When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled.
When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment.
Support for these characteristics is implementation-defined, ... C11dr §7.21.3 3
I'm just curious which conditions should be satisfied to flush stdout buffer automatically.
If code wants to insure output is certainly flushed, use fflush()
. Other conditions that may automatically flush the stream are implementation defined.
A output stream which is line-buffered shall be flushed whenever a newline is output.
An implementation may (but is not required to) flush all line-buffered output streams whenever a read is attempted from any line-buffered input stream.
Implementations are not allowed to make streams fully-buffered by default unless it can be determined that they are not associated with an "interactive device". So when stdin/stdout are terminals they can't be fully-buffered, only line-buffered (or unbuffered).
If you only need flushing when the output is to a terminal, it suffices to assume that writing a newline results in flushing. Otherwise you should explicitly call fflush
wherever you need flushing.
See the man page for setbuf(3)
. By default, stdout
is set to line buffering mode.
printf()
and its variants work with buffered output, and delegate to write()
. So this buffering is controlled by the C library implementation of printf
, with the buffer and buffer settings located in the FILE
structure.
It's also worth noting the difference between section 3 and section 2 of the unix man pages. Section 2 is made up of function calls that directly talk to the operating system and do things that it would otherwise be impossible to do from a pure user program. Section 3 is made up of function calls that a user could reproduce on their own, which often delegate to section 2 calls. Section 2 functions contain the low-level "magic" that allow C programs to interact with the outside world and perform I/O. Section 3 functions can provide a more convenient interface to the section 2 functions.
printf
, scanf
, getchar
, fputs
, and other FILE *
functions all are section 3 functions that delegate to write()
and read()
, which are section 2 functions. read()
and write()
do not buffer. printf()
interacts with the buffer in the FILE
structure, and occasionally decides to send the contents of that buffer out through write()
.
Online C2011 standard
7.21.3 Files
...
3 When a stream is unbuffered, characters are intended to appear from the source or at the destination as soon as possible. Otherwise characters may be accumulated and transmitted to or from the host environment as a block. When a stream is fully buffered, characters are intended to be transmitted to or from the host environment as a block when a buffer is filled. When a stream is line buffered, characters are intended to be transmitted to or from the host environment as a block when a new-line character is encountered. Furthermore, characters are intended to be transmitted as a block to the host environment when a buffer is filled, when input is requested on an unbuffered stream, or when input is requested on a line buffered stream that requires the transmission of characters from the host environment. Support for these characteristics is implementation-defined, and may be affected via thesetbuf
andsetvbuf
functions.
...
7 At program startup, three text streams are predefined and need not be opened explicitly — standard input (for reading conventional input), standard output (for writing conventional output), and standard error (for writing diagnostic output). As initially opened, the standard error stream is not fully buffered; the standard input and standard output streams are fully buffered if and only if the stream can be determined not to refer to an interactive device.
So, a line buffered stream will flush on a newline. On most systems I have experience with, stdout
is line buffered in an interactive session.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With