在C中,stdout缓冲区的大小是多少?

时间:2012-06-05 19:59:58

标签: c linux unix

今天我了解到当stdout设置为终端并且在不同情况下缓冲时,它是行缓冲的。因此,在正常情况下,如果我使用printf()而不使用终止'\ n',则仅当缓冲区已满时才会在屏幕上打印。如何获得这个缓冲区的大小,这有多大?

4 个答案:

答案 0 :(得分:10)

实际大小由个别实施定义;该标准没有规定最小尺寸(基于我能够找到的,无论如何)。不知道如何确定缓冲区的大小。

修改

Chapter and verse

7.19.3档案

...
3当流 unbuffered 时,字符应从源或其中显示 目的地尽快。否则可能会累积字符 作为块传输到主机环境或从主机环境传输。当流完全缓冲时, 字符旨在作为块时传输到主机环境或从主机环境传输 填充缓冲区。当流行缓冲时,字符应该是 当换行字符时,作为块发送到主机环境或从主机环境发送 遇到。此外,字符旨在作为块传输到主机 填充缓冲区时,在无缓冲流上请求输入时的环境,或 当在需要传输的线路缓冲流上请求输入时 来自主机环境的字符。 支持这些特征是 实现定义,可能会受到setbufsetvbuf函数的影响。

强调补充。

“实现定义”不是“我不知道”的委婉说法,它只是一种声明,语言标准明确地将其留给实现 define

说完了, 是一种非编程方式来查找;请参阅编译器的文档。 “实现定义”也意味着实现必须记录行为:

3.4.1

1 实施 - 定义行为
每种实施都记录了如何做出选择的非特定行为

2示例实现定义行为的示例是高阶位的传播 当有符号整数向右移位时。

答案 1 :(得分:1)

使用为默认管道大小64K创建管道时的Linux。 在/ proc / sys / fs / pipe-max-size中存在最大管道大小。 对于默认的1048576是典型的。

对于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 8192

原来这个问题可能会或可能不会得到回答。 对于一分钟的努力,最好的猜测是8千字节。

仅仅线路缓冲8K就足够了。 但是,超过行缓冲输出 与64K相比; 8K效率不高。 因为使用默认管道大小64K 如果不期望更大的管道尺寸 如果没有明确设置更大的管道尺寸 那么对于stdio缓冲区,建议使用64K。

如果需要表现 然后微薄的8K缓冲区是不够的。 通过fcntl(pipefd,F_SETPIPE_SZ,1048576) 可以增加管道的尺寸。 通过setvbuf(stdout,buffer,_IOFBF,1048576) 可以替换stdio提供的文件缓冲区。 如果没有使用管道 管道尺寸无关紧要。 但是,如果在两个进程之间传输数据 然后通过增加管道尺寸可以获得性能优势。 除此以外 通过最小的缓冲区或 由最小的管道 创造了瓶颈。

如果也读 然后通过更大的缓冲区 通过stdio,可能需要更少的读取函数调用。 用"可能"建议重要的考虑因素。 如提供的那样 通过单个写函数调用 通过单个读取函数调用 可以读取尽可能多的数据。 通过读取函数调用 可以预期返回的字节数少于请求的字节数。 通过额外的读取函数调用 可以获得额外的字节。

用于写入数据线;由stdio overkill提供。 但是,通过stdio线缓冲输出是可能的。 在某些情况下,线路缓冲输出至关重要。 如果写入proc虚拟文件系统提供的文件或 如果写入sys虚拟文件系统提供的文件 然后在一个写缓冲区中 应包括换行字节。 如果使用第二次写入 然后会出现意想不到的结果。

如果read write和stdio混合在一起 然后提出警告。 之前 写函数调用 需要fflush函数调用。 因为stderr没有缓冲; 对于stderr,不需要fflush函数调用。 通过读取,可能会提供少于预期的字节。 通过stdio,前面的字节可能已经被缓冲了。

不混合unistd和stdio I / O是很好的建议,但经常被忽略。 混合缓冲输入是不合理的。 可以混合无缓冲输入。 混合缓冲输出似乎是合理的。

通过stdio缓冲IO方便提供。 没有stdio缓冲IO是可能的。 但是,对于代码,需要额外的字节。 当充分利用足够大小的缓冲区时; 与stdio提供的输出功能相比; 写函数调用不一定慢。

但是,当不涉及管道时 然后通过功能mmap可以提供优越的IO。 在mmap的管道上,不会返回错误。 但是,在地址空间中不提供数据。 在lseek的管道上提供了错误。

最后由man 3 setvbuf提供了一个很好的例子。 如果在堆栈上,则分配缓冲区 然后在返回一个fclose函数调用之前 不能省略。

实际问题是 "在C中,什么是stdout缓冲区的大小?" 到8192,可能会有很多答案。

遇到这个询问的人 可能存在关于缓冲器输入/输出效率的好奇心。 通过一些调查,隐含地接近目标。 偏爱简洁的回复 管道尺寸的意义和 缓冲区大小的意义和 mmap没有说明。 这个回复说明了。

答案 2 :(得分:0)

here在类似问题上有一些非常有趣的答案。

在Linux系统上,您可以查看来自不同功能的缓冲区大小,包括ulimit。 此外,标题文件limits.hpipe.h应包含此类信息。

答案 3 :(得分:-2)

您可以将其设置为无缓冲,或者只是将其刷新。

当C运行时通常为您和一些示例刷新它时,这似乎有一些不错的信息。看看this