Where is the STDOUT buffer?
stdout
is a C pointer FILE
generated by the standard library, so the corresponding code is loaded as part of your C library. On Linux it will be implemented in terms of Posix file descriptors.
Both your C library and the kernel can use buffering; you will have to check individual documents. I recommend starting by looking at the relevant part of the C library source code (i.e. the part that implements <stdio.h>
), which should be very educational.
source to share
The best resource to learn about the C standard library in harrowing detail is PJ Plauger's C standard library . He describes all the problems that came up when he implemented the library himself (in MSWord! On a win3.1 laptop!)!
It also gives details on how to use (and test) each function.
For the Unix (Linux) side, you should start reading about "inode", which is a classic data structure for storing cached files in memory. The classic book for this The UNIX Operating System Design by Maurice J. Bach.
Okay, now that you are appropriately scolded for not reading all the old books and every wiki page associated with them.
Here is a relevant quote from The Standard C Library, p. 256.
Basically, you can exercise some control over how the data is buffered I / O for a stream. However, you should understand that buffering is an optimization based on various assumptions about I / O patterns. These assumptions are usually correct, and many implementations follow your advice. But they don't need it. An implementation can ignore most of your buffering requests.
However, if you think a larger buffer will improve performance, or a smaller buffer will save space, you can provide your own candidate buffer. Call the function
setvbuf
after opening the file and before performing any other operations on the stream. (Avoid the older functionsetbuf
, which is less flexible.) You can specify whether the I / O should be fully buffered, text string buffered, or unbuffered. This can affect how well your program works....
setbuf
- usesetvbuf
this function instead for more control.
setvbuf
- It is generally best to let the Standard C library decide how to buffer the I / O for you. If you are sure you do not want buffering or line buffering, use this function to properly initialize the stream. Callsetvbuf
immediately after opening the stream. Almost any operation on the stream will override your choice of buffering strategy. If you supply your own buffer with this call, don't assume the thread is actually using it. And never change the contents of the buffer while the stream is open. The argument mode (third) must have one of the values_IOFBF
,_IOLBF
or_IONBF
, as described above. Also see the MacroBUFSIZ
described [elsewhere]....
/* setbuf function */
#include "xstdio.h"
int (setbuf)(FILE *str, char *buf)
{ /* set up buffer for a stream */
setvbuf(str, buf, buf ? _IOFBF : _IONBF, BUFSIZ);
}
/* setvbuf function */
#include <limits.h>
#include <stdlib.h>
#include "xstdio.h"
int (setvbuf)(FILE *str, char *abuf, int smode, size_t size)
{ /* set up buffer for a stream */
int mode;
unsigned char *buf = (unsigned char *)abuf;
if (str->_Mode & (_MREAD|_MWRITE))
return (-1);
mode = smode == _IOFBF ? 0
: smode == _IOLBF ? _MLBF
: smode == _IONBF ? _MNBF : -1;
if (mode == -1)
return (-1);
if (size == 0)
buf = &str->_Cbuf, size = 1;
else if (INT_MAX < size)
size = INT_MAX;
if (buf)
;
else if ((buf = malloc(size)) == NULL)
return (-1);
else
mode |= _MALBUF;
if (str->_Mode & _MALBUF)
free(str->_Buf), str->_Mode &= ~_MALBUF;
str->_Mode |= mode;
str->_Buf = buf;
str->_Bend = buf + size;
str->_Next = buf;
str->_Rend = buf;
str->_Wend = buf;
return (0);
}
So, at least in this implementation, the default buffer probably lives in a FILE structure and is allocated on the heap. Here we see that its sibling, the character buffer ( str->_CBuf
), is used for "unbuffered".
source to share
It depends on how you write to stdout. If you use stdio
it will be line buffered if the output is piped to the tty. Otherwise, it will be completely buffered.
For details see man stdio
.
If you are using low-level routines such as write
only data bytes are written. Depending on the target, there will be buffering in the kernel. If the target is a tty, it can be written directly to the terminal.
source to share