Linux 在 C 中,标准输出缓冲区的大小是多少?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10904067/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
In C, what's the size of stdout buffer?
提问by user1042840
Today I learned that stdout is line buffered when it's set to terminal and buffered in different cases. So, in normal situation, if I use printf() without the terminating '\n' it will be printed on the screen only when the buffer will be full. How to get a size of this buffer, how big is this?
今天我了解到 stdout 在设置为终端时是行缓冲的,并在不同情况下缓冲。所以,在正常情况下,如果我使用 printf() 而没有终止 '\n' ,它只会在缓冲区已满时才会打印在屏幕上。如何获得这个缓冲区的大小,这个有多大?
采纳答案by John Bode
The actual size is defined by the individual implementation; the standard doesn't mandate a minimum size (based on what I've been able to find, anyway). Don't have a clue on how you'd determine the size of the buffer.
实际大小由个别实现定义;该标准没有规定最小尺寸(无论如何,基于我能够找到的)。不知道如何确定缓冲区的大小。
Edit
编辑
7.19.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 ?lled. 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 ?lled, 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-de?ned, and may be affected via thesetbuf
andsetvbuf
functions.
7.19.3 文件
...
3 当流没有缓冲时,字符会尽快从源或目标出现。否则,字符可能会作为一个块累积并传输到主机环境或从主机环境传输。当一个流被完全缓冲时,当缓冲区被填充时,字符将作为一个块传输到主机环境或从主机环境传输。当流被行缓冲时, 当遇到换行符时,字符将作为块传输到主机环境或从主机环境传输。此外,当缓冲区被填满时,当在非缓冲流上请求输入时,或者当在需要从主机传输字符的行缓冲流上请求输入时,字符将作为一个块传输到主机环境环境。对这些特性的支持是实现定义的,并且可能会受到setbuf
和setvbuf
函数的影响。
Emphasis added.
加了重点。
"Implementation-defined" is not a euphemism for "I don't know", it's simply a statement that the language standard explicitly leaves it up to the implementationto definethe behavior.
“实现定义”不是“我不知道”的委婉说法,它只是一种声明,语言标准明确地将其留给实现来定义行为。
And having said that, there isa non-programmatic way to find out; consult the documentation for your compiler. "Implementation-defined" also means that the implementation mustdocument the behavior:
而且话说回来,还有就是找出一个非编程的方式; 请查阅您的编译器的文档。“实现定义”还意味着实现必须记录行为:
3.4.1
1 implementation-de?ned behavior
unspeci?ed behavior where each implementation documents how the choice is made
2 EXAMPLE An example of implementation-de?ned behavior is the propagation of the high-order bit when a signed integer is shifted right.
3.4.1
1实现定义的行为 未
指定的行为,其中每个实现都记录了如何做出选择
2 示例 实现定义的行为的一个例子是当有符号整数右移时高位的传播。
回答by kfh
回答by fduff
hereare some pretty interesting answers on a similar question.
这里有一些关于类似问题的非常有趣的答案。
on a linux system you can view buffer sizes from different functions, including ulimit
.
Also the header files limits.h
and pipe.h
should contain that kind of info.
在 linux 系统上,您可以查看来自不同函数的缓冲区大小,包括ulimit
. 还有头文件limits.h
,pipe.h
应该包含那种信息。
回答by loquacious
The Linux when a pipe is created for default pipe size 64K is used. In /proc/sys/fs/pipe-max-size the maximum pipe size exists. For the default 1048576 is typical.
Linux 在为默认管道大小 64K 创建管道时使用。在 /proc/sys/fs/pipe-max-size 中存在最大管道尺寸。对于默认值 1048576 是典型的。
For glibc's default file buffer; 65536 bytes seems reasonable. However, ascertained by grep from the glibc source tree: libio/libio.h:#define _IO_BUFSIZ _G_BUFSIZ sysdeps/generic/_G_config.h:#define _G_BUFSIZ 8192 sysdeps/unix/sysv/linux/_G_config.h:#define _G_BUFSIZ 8192
对于 glibc 的默认文件缓冲区;65536 字节似乎合理。但是,由 glibc 源代码树中的 grep 确定:libio/libio.h:#define _IO_BUFSIZ _G_BUFSIZ sysdeps/generic/_G_config.h:#define _G_BUFSIZ 8192 sysdeps/unix/sysv/linux/_G_config.h:#define _G_BUFSIZ
By that the original question might or might not be answered. For a minute's effort the best guess is 8 kilobytes.
原来的问题可能会或可能不会被回答。对于一分钟的努力,最好的猜测是 8 KB。
For mere line buffering 8K is adequate. However, for more than line buffered output as compared with 64K; 8K is not efficient. Because for the default pipe size 64K is used and if a larger pipe size is not expected and if a larger pipe size is not explicitly set then for a stdio buffer 64K is recommended.
仅行缓冲 8K 就足够了。但是,与 64K 相比,对于多行缓冲输出;8K效率不高。因为默认管道大小使用 64K,如果不需要更大的管道大小,并且如果未明确设置更大的管道大小,则建议使用 64K 用于 stdio 缓冲区。
If performance is required then meager 8K buffers do not suffice. By fcntl(pipefd,F_SETPIPE_SZ,1048576) a pipe's size can be increased. By setvbuf (stdout,buffer,_IOFBF,1048576) a stdio provided file buffer can be replaced. If a pipe is not used then pipe size is irrelevant. However, if between two processes data is piped then by increasing pipe size a performance boon could become. Otherwise by the smallest buffer or by the smallest pipe a bottleneck is created.
如果需要性能,那么微薄的 8K 缓冲区是不够的。通过 fcntl(pipefd,F_SETPIPE_SZ,1048576) 可以增加管道的大小。通过 setvbuf (stdout,buffer,_IOFBF,1048576) 可以替换 stdio 提供的文件缓冲区。如果不使用管道,则管道尺寸无关紧要。但是,如果在两个进程之间传输数据,那么通过增加管道大小可能会带来性能优势。否则通过最小的缓冲区或最小的管道会产生瓶颈。
If reading also then by a larger buffer by stdio fewer read function invocations might be required. By the word "might" an important consideration is suggested. As by provided by a single write function invocation by a single read function invocation as much data can be read. By a read function invocation a return with fewer bytes than requested can be expected. By an additional read function invocation additional bytes may be gained.
如果还通过 stdio 读取更大的缓冲区,则可能需要更少的读取函数调用。通过“可能”一词,建议了一个重要的考虑因素。由于由单个读取函数调用的单个写入函数调用提供,因此可以读取尽可能多的数据。通过读取函数调用,可以预期返回的字节数少于请求的字节数。通过额外的读取函数调用可以获得额外的字节。
For writing a data line; by stdio overkill is provided. However, by stdio line buffered output is possible. In some scenarios line buffered output is essential. If writing to a proc virtual file system provided file or if writing to a sys virtual file system provided file then in a single write buffer the line feed byte should be included. If a second write is used then an unexpected outcome could become.
用于写入数据线;由 stdio 提供了矫枉过正。但是,通过 stdio 行缓冲输出是可能的。在某些情况下,行缓冲输出是必不可少的。如果写入 proc 虚拟文件系统提供的文件或写入 sys 虚拟文件系统提供的文件,则应在单个写入缓冲区中包含换行字节。如果使用第二次写入,则可能会出现意外结果。
If read write and stdio are mixed then caveats exist. Before a write function invocation a fflush function invocation is required. Because stderr is not buffered; for stderr the fflush function invocation is not required. By read fewer than expected bytes might be provided. By stdio the previous bytes might already be buffered.
如果读写和 stdio 混合使用,则存在警告。在写函数调用之前,需要调用 fflush 函数。因为 stderr 没有缓冲;对于 stderr,不需要调用 fflush 函数。通过读取可能提供少于预期的字节。通过 stdio 之前的字节可能已经被缓冲了。
Not mixing unistd and stdio I/O is good advise, but often ignored. Mixing buffered input is unreasonable. Mixing unbuffered input is possible. Mixing buffered output is plausible.
不混合 unistd 和 stdio I/O 是一个很好的建议,但经常被忽略。混合缓冲输入是不合理的。混合无缓冲输入是可能的。混合缓冲输出是合理的。
By stdio buffered IO convenience is provided. Without stdio buffered IO is possible. However, for the code additional bytes are required. When a sufficient sized buffer is leveraged; compared with stdio provided output functions; the write function invocation is not necessarily slower.
通过 stdio 缓冲 IO 提供了便利。没有 stdio 缓冲 IO 是可能的。但是,代码需要额外的字节。当利用足够大的缓冲区时;与stdio提供的输出函数相比;write 函数调用不一定更慢。
However, when a pipe is not involved then by function mmap superior IO can be provided. On a pipe by mmap an error is not returned. However, in the address space the data is not provided. On a pipe by lseek an error is provided.
但是,当不涉及管道时,可以通过函数 mmap 提供高级 IO。在 mmap 的管道上,不会返回错误。但是,在地址空间中不提供数据。在 lseek 的管道上提供了一个错误。
Lastly by man 3 setvbuf a good example is provided. If on the stack the buffer is allocated then before a return a fclose function invocation must not be omitted.
最后由 man 3 setvbuf 提供了一个很好的例子。如果在堆栈上分配了缓冲区,则在返回之前不得省略 fclose 函数调用。
The actual question was "In C, what's the size of stdout buffer?" By 8192 that much might be answered.
实际问题是“在 C 中,标准输出缓冲区的大小是多少?” 到 8192 可能会回答这么多。
By those who encounter this inquiry curiosity concerning buffer input/output efficiency might exist. By some inquiries the goal is implicitly approached. By a preference for terse replies the pipe size significance and the buffer size significance and mmap is not explicated. This reply explicates.
遇到这种询问的人可能会好奇关于缓冲区输入/输出效率的问题。通过一些查询,目标已经隐含地接近了。通过对简洁回复的偏好,管道大小的重要性和缓冲区大小的重要性和 mmap 没有说明。这个回复说明了。