在多个编写器的管道中交错的块?

时间:2014-10-07 11:22:52

标签: c linux unix linux-kernel

我在通过管道定义时发表以下声明:FIFO可以有多个读取器或多个写入器。来自每个编写器的字节以原子方式写入,最大大小为PIPE_BUF(Linux上为4KB)。来自同时写入器的块可以交错。类似的规则适用于同时读取。我无法理解"来自同时写入者的块可以是交错的#34;。有人可以探索吗?

3 个答案:

答案 0 :(得分:2)

您必须在Advanced Linux Programming中阅读此内容。我要说的是,这是措辞错误的,并且打算与下一段进行比较,后者说明了Windows命名管道:

  

... Win32允许在命名管道上进行多个读写器连接   没有交错数据...

但根据Windows Dev Center

  

命名管道是用于通信的命名单向或双向管道   管道服务器和一个或多个管道客户端之间。所有的实例   命名管道共享相同的管道名称,但每个实例都有自己的管道名称   缓冲区和句柄,并为客户端/服务器提供单独的管道   通讯。实例的使用允许多个管道客户端   同时使用相同的命名管道。

因此,实际上涉及多个管道连接(实例),并且在我看来,将它们与单个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。