我在通过管道定义时发表以下声明:FIFO可以有多个读取器或多个写入器。来自每个编写器的字节以原子方式写入,最大大小为PIPE_BUF(Linux上为4KB)。来自同时写入器的块可以交错。类似的规则适用于同时读取。我无法理解"来自同时写入者的块可以是交错的#34;。有人可以探索吗?
答案 0 :(得分:2)
您必须在Advanced Linux Programming中阅读此内容。我要说的是,这是措辞错误的,并且打算与下一段进行比较,后者说明了Windows命名管道:
... Win32允许在命名管道上进行多个读写器连接 没有交错数据...
命名管道是用于通信的命名单向或双向管道 管道服务器和一个或多个管道客户端之间。所有的实例 命名管道共享相同的管道名称,但每个实例都有自己的管道名称 缓冲区和句柄,并为客户端/服务器提供单独的管道 通讯。实例的使用允许多个管道客户端 同时使用相同的命名管道。
因此,实际上涉及多个管道连接(实例),并且在我看来,将它们与单个Unix管道进行比较并没有多大意义。
尽管如此,The Open Group Base Specifications说:
对管道或FIFO的写请求应以与a相同的方式处理 常规文件,但有以下例外: ... {PIPE_BUF}字节或更少字节的写请求不应交错 来自其他进程的数据在同一个管道上进行写入。写 大于{PIPE_BUF}个字节的数据可能会有数据交错打开 任意边界,由其他进程写入,无论是否 设置文件状态标志的O_NONBLOCK标志。
因此,对于Linux(POSIX)管道的单个write
请求的数据块不会被另一个写入者的请求的数据交错(中断),只要写入的字节数即可不大于PIPE_BUF。
答案 1 :(得分:2)
如果进程A尝试在进程B尝试写入PIPE_BUF(或更少)字节的同时写入PIPE_BUF(或更少)字节,则保证写入是原子的并且每个块将保持不变(尽管它们被写入的顺序是未指定的。)但是如果进程A写入的数据超过PIPE_BUF字节,则进程B中的数据可能出现在与进程A的数据交错的管道中,并且操作系统不提供任何保证来防止数据来自进程A.交错。如果要确保进程A中的所有数据保持连续,则必须将进程与其他一些机制同步。
答案 2 :(得分:-1)
假设您有两个写入器A和B,它们试图同时写入一个数据块,那么最终在管道中的数据可能看起来像ABAAAABBAABB。