管道是进程外部的(它是一个操作系统的东西),并且由进程使用读写句柄访问。许多进程可以拥有管道句柄,并且如果管理不当,可能会以各种灾难性的方式进行读写。当管道的所有句柄都关闭时,管道关闭。
尽管进程执行在 Linux 和 Windows 中的工作方式不同,但这基本上是发生的事情(我会为此被杀死!)
p1 = Popen(["dmesg"], stdout=PIPE)
创建 pipe_1,给 dmesg 一个写句柄作为它的标准输出,并在父节点中返回一个读句柄作为 p1.stdout。您现在有 1 个带有 2 个句柄的管道(在 dmesg 中写入 pipe_1,在父级中读取 pipe_1)。
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
创建管道_2。为 grep 提供 pipe_2 的写句柄和 pipe_1 的读句柄的副本。您现在有 2 个管道和 5 个句柄(pipe_1 写入 dmesg,pipe_1 读取和 pipe_2 写入 grep,pipe_1 读取和 pipe_2 在父级中读取)。
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
请注意 pipe_1 有两个读取句柄。您希望 grep 具有读取句柄,以便它读取 dmesg 数据。您不再需要父级中的句柄。关闭它,使 pipe_1 上只有 1 个读取句柄。如果 grep 死了,它的 pipe_1 读取句柄被关闭,操作系统会注意到 pipe_1 没有剩余的读取句柄,并给 dmesg 坏消息。
output = p2.communicate()[0]
dmesg 将数据发送到开始填充 pipe_1 的标准输出(pipe_1 写入句柄)。grep 读取清空 pipe_1 的标准输入(pipe_1 读取句柄)。grep 还写入填充 pipe_2 的 stdout(pipe_2 写入句柄)。父进程读取 pipe_2... 你得到了一个管道!