理解fwrite()的缓冲行为

我正在使用函数调用fwrite()将数据写入Linux上的pipe道。

之前, fwrite()被重复调用了一小块数据(平均20个字节),缓冲留给了fwrite() 。 在这个过程中显示,一次写入4096个字节的数据。

原来这个写作过程是我程序中的瓶颈。 所以我决定将我的代码中的数据缓冲到64KB的块中,然后使用fwrite()一次写入整个块。 我用setvbuf()将FILE *指针设置为“无缓冲”。

性能改善不如我预期的那么重要。

更重要的是, strace输出结果显示数据一次仍被写入4096个字节。 有人可以向我解释这种行为吗? 如果我用64KB的数据调用fwrite() ,为什么一次只写4096字节?

是否有一个替代fwrite()使用FILE *指针将数据写入pipe道?

4096来自管道下的Linux机器。 有两个地方发生。 一个是管道的容量。 容量是旧版本Linux上的一个系统页面,在32位i386机器上是4096字节。 (在更现代版本的Linux上,容量是64K。)

另一个地方,你会遇到这个4096字节的问题是在定义的常量PIPE_BUF ,保证被原子处理的字节数。 在Linux上,这是4096字节。 这个限制的意义取决于你是否将管道设置为阻塞或非阻塞。 做一个man -S7 pipe所有的血淋淋的细节。

如果您试图以很高的速度交换大量数据,则可能需要重新考虑使用管道。 你在一个Linux机器上,所以共享内存是一个选项。 您可以使用管道发送相对少量的数据作为信号机制。

如果要更改缓冲行为,则必须在fopen之后立即(或在任何I / O之前,对于标准文件句柄stdinstdoutstderr )执行此操作。 您也不想禁用缓冲,并尝试自己管理缓冲区; 相反,请指定您的64K缓冲区设置setvbuf以便它可以正确使用。

如果你真的想手动管理缓冲,不要使用stdio ; 使用较低级别的openwriteclose调用。