我不是很明白你想问什么,但是就像其他人已经告诉过你的那样,管道只不过是缓冲区而已。
从历史上来看,FIFO(或管道)会消耗用于维护它们的inode的直接块,并且它们会绑定到某个文件(无论它是否有名称)在某个文件系统中。
如今,我不知道fifo的确切实现细节,但基本上内核会缓冲所有写入数据,但读者还没有读取的数据。 FIFO具有上限(系统定义)的缓冲区量,但通常失败于10-20KB的数据。
内核进行了缓冲,但是写入者和读者之间没有延迟,因为一旦写入者在管道上写入,内核就会唤醒等待数据的所有读者。反之亦然,在管道充满数据的情况下,只要一个读者使用它,所有写入者就会被唤醒以允许再次填充它。
总之,你关于刷新的问题与管道无关(好吧,不是完全无关,让我解释一下),而是与包有关。 进行缓冲,并单独处理每个的缓冲,因此您可以在需要将其写入磁盘的缓冲区时调用刷新缓冲区的调用。
指针关联到串行tty时(它会检查调用isatty(3)调用,该调用在内部进行ioctl(2)调用,允许看到您是否正在使用串行设备,字符设备。如果发生这种情况,则进行行缓冲,这意味着每当输出一个“\n”字符到设备时,缓冲区就会自动缓冲。
这引起了优化问题,因为例如使用cat(1)复制文件时,通常最大的缓冲区是最有效的方法。好吧,来解决这个问题,因为当输出不是tty设备时,它进行完全缓冲,并且仅在指针的内部缓冲区已满时才刷新它们。
问题是:
<stdio.h>
在fifo(或pipe)节点上的行为如何?答案很简单……不是字符设备(或tty),因此
<stdio.h>
对其进行完全缓冲。如果您正在两个进程之间通信数据,并且希望读取器一旦您使用
printf(3)
输出数据就立即接收到数据,则最好使用
fflush(3)
,因为如果您不这样做,您可能会等待从未到来的响应,因为您编写的内容还没有被写入(不是由内核写入,而是由
<stdio.h>
库写入)。
正如我所说,我不知道这是否完全回答了您的问题,但肯定可以给您一个提示,让您知道问题出在哪里。
fwrite()
,fprintf()
等,但不是write()
系统调用。write()
不是stdio的一部分,也没有被C语言标准规定。相反,它属于POSIX系统接口之一。 - John Bollinger<stdio.h>
隐藏并且没有发送缓冲数据,因为缓冲区没有满,<stdio.h>
在缓冲区填满或者你强制执行fflush(3)
之前不会发送它。 - Luis Colorado