从管道读取()保证在EOF之前提供所有原子写入的数据?

Posted

技术标签:

【中文标题】从管道读取()保证在EOF之前提供所有原子写入的数据?【英文标题】:read() from pipe guaranteed to provide all atomically written data before EOF? 【发布时间】:2016-10-02 20:21:06 【问题描述】:

我正在使用一个简单的fork() 父子示例让子生成一些数据,并使用write() 为父生成一些数据。子进程将以原子方式将少于64kib(65536 字节)的数据写入管道。

父级从管道中读取,当它收到EOF时(即:假设远端已经关闭),它会继续进行一些处理逻辑,并在自己方便的时候关闭,而不关心如何孩子需要很长时间才能终止。

是否保证父级能够读取在遇到EOF 之前发送的所有客户端数据,或者是否有任何潜在的操作系统级逻辑在所有数据被发送之前提前触发EOF读了吗?

I have found a very similar question on SO, but it didn't receive an authoritative/cited answer.

谢谢。

【问题讨论】:

您的问题措辞有误。 “原子地”与它无关。由于它超过 512 字节,因此保证是原子的,但这对于您的用例来说并不重要 在 POSIX 兼容的系统中,写入/读取操作保证是原子(即,来自一个操作的数据不会与来自另一个操作的数据交错),如果bytes 最多为 PIPE_BUF。 POSIX 保证 PIPE_BUF 至少 512 字节——实际实现会有所不同。 (Ninja 编辑:在 Linux 上它曾经是 4096 字节;所以最多 4096 字节的操作保证是原子的;如果您有多个写入器写入更多,数据可能会交错。) 【参考方案1】:

是的,父级将能够读取所有数据。为了让您放心,请在 shell 中尝试以下操作:

echo test | (sleep 1; cat)

echo 命令立即执行;管道的另一端将等待一秒钟,然后尝试从中读取。这很有效。

只要父母继续循环阅读,孩子也可以毫无问题地写入超过 64 kiB,尽管这样它就不再是原子的了。

【讨论】:

请注意,如果写入的总大小超过 64 KiB,或者当前写入不能保持原子性,直到父级读取一些数据,子级才会被阻塞,直到父级读取一些数据。父母。

以上是关于从管道读取()保证在EOF之前提供所有原子写入的数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在命名管道中的 EOF 之后恢复读取

进程在写入管道之前读取数据

fprintf vs WriteFile 写入管道:无法从所有管道读取

C从管道中读取所有数据

在 Python 中使用管道文件描述符时如何检查 EOF?

使用管道时修改文件的最佳方法?