我正在使用函数调用fwrite()
将数据写入Linux上的管道。
早些时候,fwrite()
被重复调用小块数据(平均20字节),缓冲留给fwrite()
。过程表明,一次写入4096字节的数据。
原来,这个写作过程是我程序中的瓶颈。所以我决定将我的代码中的数据缓冲到64KB的块中,然后使用fwrite()
一次写入整个块。我使用setvbuf()
将FILE *指针设置为'No Buffering'。
性能改善并不像我预期的那么重要。
更重要的是,strace
输出显示数据仍然一次写入4096个字节。有人可以向我解释一下这种行为吗?如果我用64KB的数据调用fwrite()
,为什么一次只写4096个字节?
是否有fwrite()
的替代方法,可以使用FILE *指针将数据写入管道?
答案 0 :(得分:8)
4096来自作为管道基础的Linux机器。它有两个地方。一个是管道的容量。容量是旧版Linux上的一个系统页面,在32位i386机器上是4096字节。 (在更现代的Linux版本上,容量为64K。)
您遇到4096字节问题的另一个地方是定义的常量PIPE_BUF
,即保证以原子方式处理的字节数。在Linux上,这是4096字节。此限制的含义取决于您是否将管道设置为阻塞或非阻塞。为所有血腥细节做一个man -S7 pipe
。
如果您尝试以高速率交换大量数据,则可能需要重新考虑使用管道。你在Linux机器上,所以共享内存是一个选择。您可以使用管道发送相对少量的数据作为信令机制。
答案 1 :(得分:4)
如果要更改缓冲行为,必须在fopen
之后(或在任何I / O之前,标准文件句柄stdin
,stdout
,{{}之后立即执行此操作1}})。您也不想禁用缓冲并尝试自己管理缓冲区;相反,请将您的64K缓冲区指定为stderr
,以便正确使用它。
如果您真的想手动管理缓冲,请不要使用setvbuf
;使用较低级stdio
,open
和write
来电。