单个管道可以被多个进程连接和读取吗

Posted

技术标签:

【中文标题】单个管道可以被多个进程连接和读取吗【英文标题】:Can single pipe be connected and read by multiple processes 【发布时间】:2021-11-18 08:10:30 【问题描述】:

根据我的理解,C 管道就像一种特殊的文件,在内部,内核跟踪表中每个进程的打开和关闭。 see the post here

从这个意义上说:

    1个管道是否可以由多个进程连接? 如果可能,多个进程可以读取相同的数据吗? 如果 2 是可能的,它们会读取相同的数据,还是读取数据会“清空”数据?

例如:进程1写入管道,进程2,3,4能否读取进程1写入的数据?

【问题讨论】:

一个队列不能与多个阅读器一起工作,因为很难推进阅读指针。您可以使用内存中的文件。 【参考方案1】:

是的,多个进程可以读取(或写入)管道。

数据不会为进程复制。一旦一个进程从管道中读取了数据,它就会丢失,并且只有实际读取它的进程才能使用。

相反,如果您有多个进程写入单个管道,则无法区分数据或数据源自哪个进程。

【讨论】:

除非你把它作为协议的一部分。 嗨@Cheatah,您能详细说明一下您所说的协议的一部分是什么意思吗? 如果您有多个进程写入管道,并且您需要区分哪个进程写了​​一些东西,那么每个进程都可以将它们的 pid 作为消息的一部分写入。因此,每条消息都必须包含一些元信息,并且进程之间共享的信息应被视为协议。 @Cheatah 请确保每条消息的大小相同,并且不大于PIPE_BUF 字节。然后永远不要写或读部分消息。【参考方案2】:

1。 1个单管可以多进程连接吗?

是的。

2。如果可能,多个进程可以读取相同的数据吗?

不!

Unix fifos(管道)不能以“单生产者,多消费者”(spmc)方式使用;这也适用于 Unix 域套接字(对于大多数实现 UDS 和 fifos 是由完全相同的代码实现的,只有几个配置位在创建时有所不同)。写入管道/SOCK_STREAM UDS(或写入 SOCK_DGRAM unix 域套接字的数据报)的每个字节只能从一个读取端读取。

然而,完全有可能拥有一个“多个生产者,单个消费者”fifo,UDS,即消费者打开一个读取端(同时保持打开写入端,但不使用它¹ ),多个生产者可以向单个消费者发送数据。对于面向流的管道,没有严格的顺序,因此发送的所有字节都会混淆。但对于 SOCK_DGRAM UDS 套接字对,消息边界被保留。

¹:有一个特殊的陷阱,如果创建进程没有保持打开其写入端的实例,只要任何一个生产者进程关闭其写入端之一,它就会断开所有连接其他进程。

【讨论】:

以上是关于单个管道可以被多个进程连接和读取吗的主要内容,如果未能解决你的问题,请参考以下文章

持久的子进程管道 - 没有读取标准输出

在多个进程写入时读取命名管道

如何使用 subprocess.Popen 通过管道连接多个进程?

我们可以为单个数据库连接进行多个并行事务吗? [复制]

Linux进程间通信的方式都有哪些

在 mongodb-native NodeJS 中为每个子进程使用集群的单个连接池与多个连接池