1. Introduction
In C/C++, operations based on I/O streams will eventually call the system interfaces read() and write() to complete the I/O operation. To make the program run efficiently, stream objects usually provide buffers to reduce the number of calls to the system I/O interface.
There are three types of buffering methods:
(1) Full buffering. The input or output buffer is filled and the actual I/O operation will be performed. In other cases, such as forced refresh and process ending, actual I/O operations will also be performed.
For read operations, when the number of bytes read content is equal to the buffer size or the file has reached the end, or it has been forced to refresh, an actual I/O operation will be performed to read the content of the external memory file into the buffer; for write operations, when the buffer is filled or forced to refresh, an actual I/O operation will be performed, and the buffer content will be written to the external memory file. Disk file operations are usually fully buffered.
(2) Line buffering. The input or output buffer will perform actual I/O operations when encountering a newline character. The others are the same as full buffering.
(3) No buffering. Without a buffer, the data will be read into memory immediately or output to external memory files and devices. The standard error output stderr is unbuffered, which can ensure that error information is promptly fed back to the user for errors to be eliminated.
The three buffer types are defined in the header file<>
。
Buffer type | Macro |
Full buffer | _IOFBF |
Line buffering | _IOLBF |
No buffering | _IONBF |
In the Linux environment, the following piece of code can well reflect the difference between full buffering and line buffering.
#include <> #include <> int glob=6; int main(int argc, char** argv) { int var; pid_t pid; printf("a write to stdout\n"); if(pid=fork()<0) { printf("fork error"); } else { if(pid==0) { glob++; var++; } else { sleep(2); } } printf("pid=%d,glob=%d,var=%d\n",getpid(),glob,var); exit(0); }
After the compilation is successful, the default generation is generated, and the running results are as follows:
./
a write to stdout
pid=4823,glob=7,var=4195873
pid=4824,glob=7,var=4195873./ >
cat
a write to stdout
pid=4864,glob=7,var=4195873
a write to stdout
pid=4865,glob=7,var=4195873
It can be seen that when printf is output to standard output (monitor), it is a line buffer. When newlines are encountered, the buffer content will be output to the monitor and the buffer will be cleared. When using the redirect command, the standard output is redirected to the disk file. At this time, the standard output becomes full buffer. When newlines are encountered, they are not output, but are copied to the child process. After the parent-child process is finished, each has an output.
2. Buffer settings
(1) The buffer is turned on or off, and you can use the functions setbuf() or setbuffer(). The parameter buf points to the buffer, indicating that buffering is enabled, usually full buffering. Set the buf parameter to NULL to indicate that the buffering is turned off. Note that setbuffer() is a non-C standard library function and is commonly found in Linux.
The buffer length of setbuf() is at least BUFSIZ (defined in), otherwise buffer overflow may occur. setbuffer can specify the buffer size.
//@header: //@brief: Set the specified buffer or close the buffer//@param:stream: file pointer; buffer: buffer address//@notice: Use default buffer size BUFSIZ (defined in)void setbuf ( FILE * stream, char * buffer ); //@Notice: same setbuf, but can specify the buffer sizevoid setbuffer(FILE *stream, char *buf, size_t size);
Specify buffer as NULL, turn off standard output buffering.
setbuf(stdout,NULL)
Specify a new buffer.
static char newBuffer[BUFSIZ];//At least it is BUFSIZ (defined in), otherwise there may be buffer overflowsetbuf(stdout,(char*)&newBuffer); //or specify the buffer sizestatic char newBuffer[512]; setbuffer(stdout,(char*)&newBuffer,512);
(2) To change the buffering mode, you can use the function setvbuf().
//@header: //@brief: Change the buffer mode and set the buffer//@param:stream: file pointer; buf buffer address; type: buffer mode; size: buffer size//@ret:0 succeeds, non-0 failedint setvbuf(FILE *stream, char *buf, int type, unsigned size);
For example, when setting the stream buffer to row buffer, when calling setvbuf(), the buffer address is set to NULL and the buffer size is set to 0. Note that the premise is that there is a buffer.
setvbuf(stream,NULL,_IOLBF,0); //Change the buffer to line buffer //The above code is equivalent tosetlinebuf(stream); //for Linux
If the buffer size size greater than 0 is specified by calling setvbuf and the buffer buf is NULL, then the buffer size is handed over to setvbuf to malloc to apply for the buffer.
//Indirectly apply for 1024 byte full buffersetvbuf(stream,NULL,_IOFBF,1024);
The above is the detailed content of C/C++'s full buffering, line buffering and unbuffered C/C++. For more information about C/C++ buffering, please pay attention to my other related articles!