Fifos in Linux 数据包模式

Fifos in Linux in packet mode

我已经阅读了 pipe2 的 Linux manpage,其中指出您可以使用 O_DIRECT 标志创建一个以数据包模式执行 I/O 的管道。

虽然我听说管道和 fifos 在 Linux 中共享很多代码,但我还没有发现任何与 fifos(命名管道)类似的东西,并且它可能对我的项目有用(我们已经在 fifos 中传递消息,但我们必须寻找一个特殊的终止符,一次读取一个字节)。

有什么等同于在数据包模式下执行 fifo I/O 吗?

文件描述符上的 O_* 标志通常可以通过 fcntl(fd, F_SETFL, ...) 更改,但在这种情况下,我认为它不会起作用,因为:

https://lkml.org/lkml/2015/12/15/480

这是一个 2 周前提交的补丁,正好支持这个用例,唯一的回复是来自自动化测试人员的几次构建失败。

因此您可以尝试修复该补丁并应用它(应该很容易 - 看起来像打字错误,f 应该是 filp)...

或(这是我更喜欢的选项)看看您的需求是否可以通过 AF_UNIXSOCK_SEQPACKET 套接字而不是带有此新标志的管道来满足。它们更强大并且更便携。

(我假设您在打开命名管道时已经尝试将 O_DIRECT 传递给 open,因为这是最明显的事情。)

pipe&fifo都是字节流,开一个file descriptor,然后用read()write()进行通信

如果你想要一个packet(我不确定你的意思,我假设你想读取一个数据块而不需要自己确定边界),POSIX - message queue可能是一个不错的选择选择。它以消息为单位发送/接收数据,而不是逐字节发送。

也可以在消息上设置priority改变接收顺序,如果所有消息的优先级相同(例如0),则发送和接收顺序与FIFO相同。

如果这就是您想要的,请查看 man mq_overview 了解详情。

我无法切换到套接字或消息队列,并且无法使用管道。但好消息是,user2404501 的回答中提到的补丁最终被接受并在 linux v4.5 和更新版本中。所以使用 fnctl() 在命名管道上设置 O_DIRECT 是有效的。

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=0dbf5f20652108106cb822ad7662c786baaa03ff