Python 为什么我的Popen管会堵塞?
我试图将一些数据提供给一系列相互连接的进程 通过管道。然而,我无法关闭它Python 为什么我的Popen管会堵塞?,python,subprocess,pipe,Python,Subprocess,Pipe,我试图将一些数据提供给一系列相互连接的进程 通过管道。然而,我无法关闭它 p1 = subprocess.Popen("sort", stdin=subprocess.PIPE, stdout=subprocess.PIPE) p2 = subprocess.Popen("uniq", stdin=p1.stdout, stdout=subprocess.PIPE) p1.communicate(r""" a b c a""") out, _ = p2.communicate() print(
p1 = subprocess.Popen("sort", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p2 = subprocess.Popen("uniq", stdin=p1.stdout, stdout=subprocess.PIPE)
p1.communicate(r"""
a
b
c
a""")
out, _ = p2.communicate()
print(out)
程序现在只是在等待。是否有其他方法可以向p1发出输入结束的信号
--注意:我正在windows上运行您需要在第一个程序上关闭stdin 需要注意的一些事项:
sort
需要在能够排序之前读取完整的输入(如果您还不知道它们是什么,则无法排序)2
,它有自己的缓冲区,用于收集并等待文件描述符关闭,表示已完成;)
编辑:这是我举的一个例子。我个人认为直接使用管道更干净,因为您可以在生成流程之前单独构建输入:
In [2]: import os
...: import subprocess
...:
...: # A raw os level pipe, which consists of two file destriptors
...: # connected to each other, ala a "pipe".
...: # (This is what subprocess.PIPE sets up btw, hence it's name! ;)
...: read, write = os.pipe()
...:
...: # Write what you want to it. In python 2, remove the `b` since all `str`ings are `byte` strings there.
...: os.write(write, b"blahblahblah")
...:
...: # Close stdin to signal completion of input
...: os.close(write)
...:
...: # Spawn process using the pipe as stdin
...: p = subprocess.Popen(['cat'], stdin=read)
...:
blahblahblah
另外,请确保您
p.wait()
等待流程的完成,否则您可能会遇到尚未获得完整结果的情况。免责声明:这里不是专家。我以前没有使用过communicate()
,但是
首先,在读取时,它意味着从正在运行的进程的stdout/stderr中读取数据:
从stdout和stderr读取数据
因此,我猜p1
执行sort
的输出会被python程序读取。或者更准确地说,在我的Linux机器上,行为似乎不是确定性的——有时是Python代码,有时是读取p1/sort
标准输出的p2/uniq
。我猜他们只是在争夺数据
看起来communicate()
是一种组合,对于您的用例(使用p1/sort
)来说,它做得有点太多了。使用p2/uniq也可以
另一方面,如果您尝试:
import subprocess
p1 = subprocess.Popen("sort", stdin=subprocess.PIPE, stdout=subprocess.PIPE)
p2 = subprocess.Popen("uniq", stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdin.write(r"""
a
b
c
a""")
p1.stdin.close()
out, _ = p2.communicate()
print(out)
它似乎起作用了。FWIW(在Linux上运行)该程序确实结束了(而且大部分时间不打印任何内容)