例如,我创建了一个如下所示的命名管道:
mknod myPipe p
我从某个进程(例如某个服务器)中读取它。出于示例目的,我使用了 tail:
tail -f myPipe
如果多个客户端进程向其中写入一些消息(例如,echo "msg" >> myPipe
消息是否有可能交错,如下所示:
<beginning of message1><message2><ending of message1>
或者写入命名管道的过程是原子的?
答案1
这取决于每个进程写入的量(假设您的操作系统在这方面符合 POSIX 标准)。从write()
:
对管道或 FIFO 的写请求应以与常规文件相同的方式处理,但有以下例外:
[...]
- {PIPE_BUF} 字节或更少的写入请求不得交错来自其他进程的数据在同一管道上进行写入。大于 {PIPE_BUF} 字节的写入可能会在任意边界上与其他进程的写入交错数据,无论文件状态标志的 O_NONBLOCK 标志是否设置。
也在基本原理部分关于管道和 FIFO:
- 原子/非原子:如果一个操作中写入的总量不与任何其他进程的数据交错,则写入是原子的。当有多个写入器向单个读取器发送数据时,这非常有用。应用程序需要知道可以原子执行多大的写入请求。该最大值称为 {PIPE_BUF}。 POSIX.1-2008 本卷并未说明超过 {PIPE_BUF} 字节的写入请求是否是原子的,而是要求 {PIPE_BUF} 或更少字节的写入必须是原子的。
if 的值PIPE_BUF
由每个实现定义,但最小值为 512 字节(请参阅limits.h
)。在 Linux 上,它是 4096 字节(请参阅pipe(7)
)。