并发写入命名管道的保证是什么?

Rog*_*ach 34 linux pipe

例如,我创建了一个命名管道,如下所示:

mknod myPipe p
Run Code Online (Sandbox Code Playgroud)

我从某个进程(例如,某个服务器)中读取了它。例如,我使用了尾巴:

tail -f myPipe
Run Code Online (Sandbox Code Playgroud)

如果多个客户端进程将一些消息写入其中(例如,echo "msg" >> myPipe,消息是否有可能交错,如下所示:

 <beginning of message1><message2><ending of message1>
Run Code Online (Sandbox Code Playgroud)

或者写入命名管道的过程是原子的?

Mat*_*Mat 30

这取决于每个进程的写入量(假设您的操作系统在这方面符合 POSIX 标准)。来自write()

对管道或 FIFO 的写请求应以与常规文件相同的方式处理,但以下例外:
[...]

  • {PIPE_BUF} 字节或更少字节的写入请求不应与在同一管道上进行写入的其他进程的数据交错。无论是否设置了文件状态标志的 O_NONBLOCK 标志,大于 {PIPE_BUF} 字节的写入可能会在任意边界上将数据与其他进程的写入交错。

同样在关于管道和 FIFO的基本原理部分

  • 原子/非原子:如果在一个操作中写入的全部量不与来自任何其他进程的数据交错,则写入是原子的。当有多个写入器向单个读取器发送数据时,这很有用。应用程序需要知道可以预期以原子方式执行的写入请求有多大。此最大值称为 {PIPE_BUF}。POSIX.1-2008 的这一卷并没有说明超过 {PIPE_BUF} 字节的写请求是否是原子的,但要求 {PIPE_BUF} 或更少字节的写是原子的。

值 ifPIPE_BUF由每个实现定义,但最小值为 512 字节(请参阅 参考资料limits.h)。在 Linux 上,它是 4096 字节(请参阅 参考资料pipe(7))。

  • 顺便说一下,PIPE_BUF 保证至少为 512。请注意,您还必须保证您的进程 _actually_ 在单个 write 调用中将每一行写入其中。启用行缓冲 (`setvbuf(stdout, NULL, _IOLBF,512)`) 将不需要你使用低级函数。 (5认同)
  • @AlexanderMills:不,那是最小值 (2认同)
  • 规范规定最多可以原子写入 PIPE_BUF 字节,并且不会与任何其他写入器交错。并且 PIPE_BUF 保证是 512 或更大的数字。 (2认同)