我是否需要冲洗命名管道?
收藏

我找不到命名管道是否被缓冲,因此有一个问题。
手册上说:
fifo特殊文件类似于管道…任何进程都可以像普通文件一样打开它进行读写。
管道没有缓冲,不需要冲洗。但在一个普通的文件中,我会使用fflush(或fsync)文件描述符。
命名管道怎么样?


最佳答案:

管道没有缓冲,不需要冲洗。
实际上,我是反过来说的:对于大多数意图和目的来说,管道只是缓冲区。刷新它们没有意义,因为没有接收数据的底层设备。
此外,尽管posix没有明确禁止额外的管道i/o缓冲,但它确实提出了足够的行为要求,我认为没有任何方法可以通过观察来确定是否发生了这种缓冲,除非可能是通过fsync()是否成功。换言之,即使有额外的缓冲,也不必fsync()管端。
但在普通档案里,我
将fflush(或fsync)文件描述符。
不,你不会fflush()一个文件描述符。fflush()操作流,由FILE对象表示,而不是文件描述符。这是一个关键的区别,因为大多数流在C库级别进行缓冲,与下面文件的性质无关。正是这个库级缓冲区与fflush()交互。您可以通过setvbuf()函数控制流的库级缓冲模式。
在那些提供它的系统上,fsync()以不同的、较低的级别运行。它指示操作系统确保以前写入指定文件描述符的所有数据都已传递到底层存储设备。换句话说,它刷新操作系统级缓冲区。
请注意,可以通过fdopen()函数将流包装在管道结束文件描述符周围。这不会使管道比以前更需要刷新,但默认情况下流将被缓冲,因此刷新将与之相关。
还要注意的是,一些存储设备执行自己的缓冲,因此即使在将数据传递给存储设备之后,也不能确定它们是否立即持久化。
命名管道怎么样?
上面关于流i/o与基于posix描述符的i/o的讨论也适用于这里。如果通过流访问命名管道,那么它与fflush()的交互将取决于该流的缓冲。
但我想你的问题更多的是关于操作系统级的缓冲和刷新。POSIX似乎没有说得太具体,但是由于您标记了[Linux]并在您的问题中引用了Linux手册页,因此我提供这个回答:
管道和先进先出的唯一区别是
它们被创建和打开。一旦这些任务完成,
管道和fifos上的i/o具有完全相同的语义。
Linux pipe(7) manual page.

    公众号
    关注公众号订阅更多技术干货!