【问题标题】:Default buffer size for a file on LinuxLinux 上文件的默认缓冲区大小
【发布时间】:2013-08-14 04:48:35
【问题描述】:

documentation 声明缓冲的默认值为:If omitted, the system default is used。我目前使用的是 Red Hat Linux 6,但我无法确定为系统设置的默认缓冲。

谁能指导我如何确定系统的缓冲?

【问题讨论】:

    标签: python linux file buffer rhel6


    【解决方案1】:

    我不确定这是不是正确的答案,但python 3.0 librarypython 20 library 都以与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】:

      由于您链接到 2.7 文档,我假设您使用的是 2.7。 (在 Python 3.x 中,这一切都变得简单多了,因为更多的缓冲暴露在 Python 级别。)

      所有open 实际上(在 POSIX 系统上)都是调用fopen,然后,如果你为buffering 传递了任何东西,setvbuf。由于您没有传递任何内容,因此您最终会得到来自 fopen 的默认缓冲区,这取决于您的 C 标准库。 (有关详细信息,请参阅the source。没有buffering,它将-1 传递给PyFile_SetBufSize,除非bufsize >= 0,否则它什么都不做。)

      如果您阅读了glibc setvbuf manpage,它说明如果您从不调用任何缓冲函数:

      通常所有文件都是块缓冲的。当对文件进行第一次 I/O 操作时,会调用malloc(3),并获得一个缓冲区。

      请注意,它并没有说明获得了什么大小的缓冲区。这是故意的;这意味着实现可以是智能的,并为不同的情况选择不同的缓冲区大小。 (有一个BUFSIZ 常量,但仅在调用setbuf 等遗留函数时使用;不保证在任何其他情况下使用。)

      那么,会发生什么?好吧,如果你看一下glibc的源码,最终它调用了宏_IO_DOALLOCATE,它可以被hook(或者被覆盖,因为glibc统一了C++ streambuf和C stdio缓冲),但最终它分配了一个_IO_BUFSIZE的buf,这是特定于平台的宏_G_BUFSIZE 的别名,即8192

      当然,您可能希望在自己的系统上追踪宏,而不是相信通用来源。


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

      【讨论】:

      • 伟大的解释 abarnert!谢谢。
      【解决方案3】:
      #include <stdio.h>
      
      int main(int argc, char* argv[]){
        printf("%d\n", BUFSIZ);
        return 0;
      }
      

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

      【讨论】:

      • 不,这不能保证是默认缓冲区大小;它只是用于 setbuf 等遗留函数的缓冲区大小。
      • 如果是这种情况,那么这个参数就没有多大帮助:[2] 指定缓冲区大小目前对没有 setvbuf() 的系统没有影响。指定缓冲区大小的接口不是使用调用 setvbuf() 的方法完成的,因为在执行任何 I/O 后调用时可能会转储内核,并且没有可靠的方法来确定是否是这种情况。跨度>
      • 哪个参数?你在哪个系统上setvbuf(3) 有脚注?第三,CPython 2.7 very clearly calls setbuf如果setvbuf不可用,那么它就没有效果是不正确的。 (确实,任何正值都与setbuf-only 系统上的任何其他正值具有相同的效果,但这绝对不是no 效果。)最后,它清楚地调用setvbuf如果 is 可用,那么您认为它不能这样做的论点是没有实际意义的。
      • 感谢您提供更好的答案。
      • 我不确定我的答案是否合适;只是真的没有一个好的答案。没有记录在案的方法可以获取此信息……
      猜你喜欢
      • 1970-01-01
      • 2013-06-03
      • 1970-01-01
      • 1970-01-01
      • 2012-05-08
      • 2015-06-07
      • 2011-01-06
      • 2012-04-05
      • 1970-01-01
      相关资源
      最近更新 更多