登录

python - subprocess.Popen文档 示例代码意义求解惑

原文链接

output=`dmesg | grep hda`
# becomes
p1 = Popen(["dmesg"], stdout=PIPE)
p2 = Popen(["grep", "hda"], stdin=p1.stdout, stdout=PIPE)
***p1.stdout.close()  # Allow p1 to receive a SIGPIPE if p2 exits.***
output = p2.communicate()[0]

关于 SIGPIPE 信号,我找到这样的描述 "如果你试图向一个管道或套接口写入,当读取方关闭连接,你将得到一个SIGPIPE的信号,它会使进程终止除非指定处理方法。"

从大概的意思来看, 关闭 p1.stdout 是为了让 p1 收到 SIGPIPE 信号。但是内在原因不能理解。

我们建立了 p1 到 p2 的管道,为什么还要 take care 他们之间的通信呢?

# Python
阿神 阿神 2560 天前 238 次浏览

全部回复(2) 我要回复

  • 迷茫

    迷茫2017-04-17 15:24:43

    这个信号的意义在于:你创建一个管道 A | B ,当B执行结束了以后,很多情况下A的继续执行是没有意义的,这时候发送一个SIGPIPE给A,默认情况下(没有对应的Sig Handler)A就终止了;当然,在需要的情况下,A可以设置一个handler来处理这个信号。

    回复
    0
  • PHPz

    PHPz2017-04-17 15:24:43

    当进程P1 尝试向一个管道写入数据,而管道的另一端没有进程连接时,P1将受到SIGPIPE 信号。
    在上述例子中,
    当p1,p2 创建完毕,管道p1.stdout 和 p2.stdin 都连接到该管道。
    这时关闭p1.stdout, 则只有p2.stdin 从该管道读取数据。
    这样,当p2 结束时,p1 再向管道写入数据,就会收到SIGPIPE 信号。

    换言之,如果没有p1.stdout.close(), 则p1.stdout 一直连接管道,p1 不会收到SIGPIPE.

    回复
    0
  • 取消 回复 发送