c++ - C++ 中的缓冲区大小

标签 c++ c linux io buffering

我正在观察 C++ Std 库方法 std::ostream::write() 的以下行为。

为了缓冲数据,我使用了以下 C++ API

std::ofstream::rdbuf()->pubsetbuf(char* s, streamsize n)

只要我们在文件流上写入的数据大小 (datasize) 使用

std::ofstream::write (const char* s, datasize n)

小于 1023 字节(低于此值,写入将累积到缓冲区未满),但当要写入的数据大小超过 1023 时,将不考虑缓冲区并将数据刷新到文件.

例如如果我将缓冲区大小设置为 10KB 并一次写入大约 512 个字节,strace 将显示多个写入已合并为一个写入

writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240 ( 10 KB )
writev(3, [{"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 9728}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 512}], 2) = 10240
...

但是当我一次写入 1024 字节(保持缓冲区固定为 10 KB)时,现在 strace 显示它没有使用缓冲区并且每个 ofstream::write 调用都被转换为 write 系统调用。

writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024 ( 1KB )
writev(3, [{NULL, 0}, {"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"..., 1024}], 2) = 1024
...

是否缺少任何 C++ API 调用或 Linux 调优参数?

最佳答案

这是 libstdc++ 的实现细节,在 bits/fstream.tcc 的第 650 行附近实现。基本上,如果写入大于 2^10,它将跳过缓冲区。

如果你想知道这个决定背后的理由,我建议你给 libstdc++ 开发列表发邮件。

http://gcc.gnu.org/ml/libstdc++/

关于c++ - C++ 中的缓冲区大小,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22477671/

相关文章:

java - Google ProtoBuf 序列化/反序列化

c++ - Makefile 目标错误

c - RPC windows获取客户端IP地址

c - 内核如何知道物理页面由两个不同的进程共享?

c++ - 如何在 Windows 上将 lld 与 CMake 一起使用?

c++ - 不能在 C++ 中的另一个对象中更改对象的属性

linux - 删除存储在 LAN 中的整个终端历史记录

linux - 我的 Perl 程序如何在 Linux 上获得标准输入?

c++ - 我们如何在 linux 中使用 c 或 c++ 调用系统函数,如 pwd 或 ls -l 而无需使用 system() 或 exec() 函数?

c - 带有Linux的C中套接字的奇怪段错误