Linux上文件的默认缓冲区大小

22

根据文档,默认缓冲值为:如果未指定,则使用系统默认值。我目前在Red Hat Linux 6上,但我无法确定系统设置的默认缓冲。

请问有人可以指导我如何确定系统的缓冲?

3个回答

30

由于您链接到了2.7文档,我假设您正在使用2.7版本。在Python 3.x中,这一切变得更加简单,因为更多的缓冲区在Python级别上被暴露出来。

实际上,open(在POSIX系统上)所做的全部工作只是调用fopen,然后如果您传递了任何buffering,它会调用setvbuf。由于您没有传递任何内容,所以您最终只能获得fopen的默认缓冲区,该缓冲区是根据您的C标准库而定的。(有关详细信息,请参见来源。如果没有buffering,则它将-1传递给PyFile_SetBufSize,除非bufsize > = 0)。

如果您阅读glibc setvbuf manpage,它会解释如果您从未调用任何缓冲函数:

Normally all files are block buffered. When the first I/O operation occurs on a file, malloc(3) is called, and a buffer is obtained. 请注意,它并没有说明获得的缓冲区大小。这是故意的。这意味着实现可以聪明地为不同情况选择不同的缓冲区大小。(有一个BUFSIZ常量,但只用于调用遗留函数时,如setbuf;不能保证在其他任何情况下使用。)
所以,发生什么事呢?嗯,如果您查看glibc源代码,最终它调用宏_IO_DOALLOCATE,该宏可以被挂钩(或覆盖,因为glibc统一了C++ streambuf和C stdio缓冲),但最终,它会分配一个大小为_IO_BUFSIZE的buf,_IO_BUFSIZE是平台特定的宏_G_BUFSIZE的别名,其值为8192
当然,您可能想追踪自己系统上的宏,而不是相信通用源代码。

你可能会想知道为什么没有很好的记录方法来获取这些信息。据推测,这是因为你不应该关心。如果需要特定的缓冲区大小,则手动设置一个;如果相信系统最懂得,那就信任它。除非你真正在内核或libc上工作,否则谁在乎呢?理论上,这也留下了系统可以在此做一些聪明事情的可能性,比如基于文件系统的块大小或基于运行统计数据选择bufsize,尽管看起来像linux/glibc、FreeBSD或OS X除了使用一个常数外,似乎没有其他选择。而且对于大多数应用程序来说,这确实并不重要。(你可能想自己测试一下——在某些缓冲I/O限制脚本上使用从1 KB到2 MB的显式缓冲区大小,看看性能差异如何。)


很好的解释abarnert!谢谢。 - falconepl

23

我不确定这是否是正确的答案,但是 Python 3.0库Python 20库 都以与 open() 文档中描述默认值相同的方式描述了 io.DEFAULT_BUFFER_SIZE。巧合吗?

如果不是,那么对我来说答案就是:

$ python
>>> import io
>>> io.DEFAULT_BUFFER_SIZE
8192

$ lsb_release -a
No LSB modules are available.
Distributor ID: Ubuntu
Description:    Ubuntu 14.04.1 LTS
Release:        14.04
Codename:       trusty

-2
#include <stdio.h>

int main(int argc, char* argv[]){
  printf("%d\n", BUFSIZ);
  return 0;
}

我使用了'man setvbuf'来查找这个。setvbuf是文档页面的脚注[2]。


不,那并不能保证是默认缓冲区大小;它只是用于遗留函数(如setbuf)的缓冲区大小。 - abarnert
如果是这种情况,那么该参数并没有什么帮助:[2] 目前,在没有 setvbuf() 的系统上指定缓冲区大小没有任何效果。指定缓冲区大小的接口不是使用调用 setvbuf() 的方法完成的,因为在执行任何 I/O 后调用该方法可能会导致核心转储,并且没有可靠的方法来确定是否出现了这种情况。 - seanmcl
哪个参数?你在什么系统上,setvbuf(3)有脚注?第三,CPython 2.7非常明确地调用setbuf,如果setvbuf不可用,因此它并非没有效果。 (对于仅使用setbuf的系统,任何正值都具有与其他正值相同的效果,但这仍然绝对不是“没有”效果。)最后,它显然会调用setvbuf,所以你认为它不能这样做的论点是无效的。 - abarnert
感谢您的更好答案。 - seanmcl
我不确定我的答案是否好,只是实际上并没有一个好的答案。没有明确的方法来获取这个信息... - abarnert

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接