在我的python程序中,我有两个subprocesses
通过pipe
互连,一个连接到stdin
,另一个连接到stdout
。我的问题是,当数据流结束时,子进程会挂起,直到我按下ctrl+c
。它看起来像子过程被打开我的管道。如果我能告诉流经管道的数据何时可以手动关闭它。
def write(tag_name):
p_r, p_w = os.pipe()
pv = subprocess.Popen('pv', stdin=None, stdout=p_w)
dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=p_r, stdout=None)
dd.wait()
答案 0 :(得分:2)
只是不要使用os.pipe()
,您可以将子流程stdout
直接传递给其他流程stdin
,如下所示:
def write(tag_name):
pv = subprocess.Popen('pv', stdin=None, stdout=subprocess.PIPE)
dd = subprocess.Popen('dd bs=64k of=/dev/nst0'.split(), stdin=pv.stdout, stdout=None)
dd.wait()
当第一个命令结束时,管道被破坏(而不是需要手动关闭的os.pipe()
),因此它也会结束第二个命令并且脚本可以继续/结束。
我已经测试了一个简单的管道命令,并且os.pipe()
它会在您描述的结尾处阻塞,但在第一个进程以我的修改结束时退出。
答案 1 :(得分:0)
这里需要一个非阻塞解决方案。 看看我的解决方案:https://github.com/vesellov/bitdust.devel/blob/master/system/nonblocking.py
你可以这样调用它(没有测试代码):
import nonblocking, time
p = nonblocking.Popen('pv'.split(), shell=True, )
p.make_nonblocking()
while 1:
if p.state() == nonblocking.PIPE_CLOSED:
# pipe closed, stop
return break
if p.state() == nonblocking.PIPE_READY2READ:
newchunk = p.recv(1024)
if newchunk == '':
# EOF reached, stop
break
# do something with the data here
# you can send it to second stream
try:
time.sleep(0.01)
except KeyboardInterrup:
break
所以当你调用dd.wait()时它会阻塞,这就是你的Ctrl-C无法正常工作的原因。你需要手动处理这个问题....非阻塞流媒体在Python中不是一个简单的故事。退房Twisted project,你可以找到很多很酷的东西:-)