今天,我了解到stdout被设置为terminal并在不同情况下进行缓冲时,会进行行缓冲。 所以,在正常情况下,如果我使用printf()而不终止'\ n',只有当缓冲区满时,它才会被打印在屏幕上。 如何获得这个缓冲区的大小,这是多大?
实际大小由个别实现来定义; 该标准并没有规定最小尺寸(基于我已经能够找到,无论如何)。 不知道如何确定缓冲区的大小。
编辑
章节和诗句 :
7.19.3文件
…
3当一个流没有缓冲的时候 ,字符应该尽快从源头或目的地出现。 否则,字符可以积累并作为一个块被传送到主机环境或从主机环境传送。 当一个流被完全缓冲时 ,当缓冲区被填满时,字符将作为一个块被传输到主机环境或从主机环境传输。 当一个流是行缓冲的时候 ,当遇到一个换行符时 ,字符被打算作为一个块被传送到主机环境或从主机环境传送出去。 此外,当填充缓冲区,当在非缓冲流上请求输入时,或者在需要从主机环境传输字符的线路缓冲流上请求输入时,字符将作为块被传输到主机环境。 对这些特性的支持是实现定义的,可能会受到setbuf
和setvbuf
函数的影响 。
重点补充。
“实现定义”不是“我不知道”的委婉说法,只是语言标准明确地将其落实到实施中来定义行为。
说了这么多,有一个非程序化的方法来查明; 请参阅您的编译器的文档。 “实施定义”也意味着实施必须记录行为:
3.4.1
1 实现定义的行为
未明确的行为,其中每个实施文件如何做出选择2示例实现定义的行为的示例是当有符号整数向右移位时高位的传播。
使用默认管道大小64K创建管道时的Linux。 在/ proc / sys / fs / pipe-max-size中存在最大管道大小。 对于默认的1048576是典型的。
对于glibc的默认文件缓冲区; 65536字节似乎是合理的。 但是,通过grep从glibc源代码树中确定: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
由此,原来的问题可能会或可能不会得到回答。 一分钟的努力,最好的猜测是8千字节。
仅仅缓冲8K就足够了。 但是,对于比64K多的行缓冲输出, 8K效率不高。 因为默认管道大小为64K,所以如果不需要更大的管道尺寸,并且没有明确设置较大的管道尺寸,则建议使用stdio缓冲区64K。
如果需要性能,微薄的8K缓冲区是不够的。 通过fcntl(pipefd,F_SETPIPE_SZ,1048576)可以增加管道的尺寸。 通过setvbuf(stdout,buffer,_IOFBF,1048576)可以替换一个stdio提供的文件缓冲区。 如果没有使用管道,那么管道尺寸是不相关的。 但是,如果在两个过程数据之间进行管道连接,那么通过增加管道尺寸就可以获得性能优势。 否则,由最小的缓冲区或由最小的管道创建一个瓶颈。
如果通过stdio读取更大的缓冲区,则可能需要更少的读取函数调用。 用“可能”这个词提出一个重要的考虑。 由单个读函数调用所提供的单个读函数调用尽可能多的数据可被读取。 通过读取函数调用,可以预期具有比请求更少的字节的返回。 通过附加的读取函数调用,可以获得额外的字节。
写数据线; 由stdio矫枉过正提供。 但是,通过stdio行缓冲输出是可能的。 在某些情况下,行缓冲输出是必不可少的。 如果写入proc虚拟文件系统提供的文件,或者如果写入sys虚拟文件系统提供的文件,则在单个写缓冲区中应该包括换行字节。 如果使用第二次写入,则可能会出现意想不到的结果。
如果读写和stdio混合,则存在警告。 在写函数调用之前,需要fflush函数调用。 因为stderr没有被缓冲; 对于stderr来说,fflush函数的调用是不需要的。 通过读取可能会提供少于预期的字节。 通过stdio,以前的字节可能已经被缓冲了。
不混合unistd和stdio I / O是很好的建议,但往往被忽略。 混合缓冲输入是不合理的。 混合无缓冲输入是可能的。 混合缓冲输出是合理的。
通过stdio缓冲IO提供了方便。 没有stdio缓冲IO是可能的。 但是,对于代码,需要额外的字节。 当足够大小的缓冲区被杠杆化时; 与stdio提供的输出功能相比; 写函数调用不一定比较慢。
但是,当不涉及管道时,可以通过函数mmap提供上级IO。 在mmap的管道上,不会返回错误。 但是,在地址空间中不提供数据。 在lseek的管道上提供了一个错误。
最后由man 3 setvbuf提供了一个很好的例子。 如果在堆栈中分配了缓冲区,那么在返回之前不能省略fclose函数调用。
实际的问题是“在C中,标准输出缓冲区的大小是多少? 到8192年,可能会有很多答案。
那些遇到这种询问的人可能会对缓冲器输入/输出效率产生好奇。 通过一些询问,这个目标已经被隐含地接近了。 通过对简短回复的优先选择,管道大小显着性和缓冲区大小显着性和mmap不被解释。 这个答复说明。
对于类似的问题, 这里有一些非常有趣的答案。
在Linux系统上,您可以查看不同功能的缓冲区大小,包括ulimit
。 头文件limits.h
和pipe.h
应该包含这种信息。
你可以将它设置为无缓冲,或只是刷新它。
这似乎有一些不错的信息,当C运行库通常刷新它为您和一些例子。 看看这个 。