2

假设我有一个生成一些数据的进程,并且这些数据由两个彼此独立的不同进程使用。

解决此问题的一种方法是将生成的数据写入文件,然后让其他两个进程从文件中读取。如果文件的大小不大,这会很好,但是如果有很多数据,IO 会变得很昂贵。

如果我只有一个进程使用数据,我可以使用连接这两个进程,os.pipe()并将数据从一个的输出汇集到另一个的输入。

但是,由于我有两个消费者进程,我不确定是否有一种方法可以复制管道的读取端,以便两个消费者都可以从中读取。

4

2 回答 2

2

管道中的数据只能读取一次。但是,您可以使用一个中间过程来简单地复制数据并将其写入两个不同的文件描述符。在 Unix 系统上,这是由标准工具完成的tee。POSIX shell 中的一个示例:

$ exec 4> a
$ seq 3 | tee /dev/fd/4 > b

这会将 的输出写入seq 3两个文件ab.

你可以在 Python 中做同样的事情,使用一个调用os.pipe()和进程调用的组合,以及subprocess.Popen()对你想要连接的每个进程的调用。teesubprocess.Popen()

producer = subprocess.Popen(["seq", "3"], stdout=subprocess.PIPE)
pipe_r, pipe_w = os.pipe()
tee = subprocess.Popen(["tee", "/dev/fd/{}".format(pipe_w)],
                       stdin=producer.stdout, stdout=subprocess.PIPE)
consumer1 = subprocess.Popen(["cat"], stdin=tee.stdout)
consumer2 = subprocess.Popen(["cat"], stdin=pipe_r)
producer.wait()
tee.wait()
consumer1.wait()
consumer2.wait()
os.close(pipe_r)
os.close(pipe_w)
于 2013-08-09T17:53:27.317 回答
0

因此,由于它是由 Pipe 返回的文件描述符,我很遗憾地说您无法返回;不过,一个想法是让任一读取器进程将数据添加到multiprocessing.Queue两者都可以读取并随后删除数据的位置。

您也可以始终拥有从写入器进程到每个读取器的管道。还有其他的东西,比如shared memory或者dbus你可以用来传送数据。

你能更深入地描述你的问题吗?

根据平台的不同,您也可以让进程使用多个流——例如标准输出和第四个流——但这在操作系统之间是不可移植的。

于 2013-08-09T17:25:07.350 回答