[英]Python subprocess.Popen PIPE and SIGPIPE
While I browsed posts, I ran into this example below on here , It is saying proc1.stdout.close()
is needed to be called for appropriate exit of proc1
, generating SIGPIPE
. 当我浏览帖子时,我在这里遇到了这个例子,这就是说需要调用
proc1.stdout.close()
以适当退出proc1
,生成SIGPIPE
。
import subprocess
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc1.stdout.close() # Allow proc1 to receive a SIGPIPE if proc2 exits.
out, err = proc2.communicate()
print('out: {0}'.format(out))
print('err: {0}'.format(err))
However, I am not clear on that. 但是,我不清楚这一点。 Please fix my understanding.
请理解我的理解。
SIGPIPE
occurs when a PIPE
tries to write to closed PIPE
. PIPE
尝试写入已关闭的PIPE
时发生SIGPIPE
。 PIPE
is proc1
's stdout
and reader PIPE
is proc2
's stdin
. PIPE
是proc1
的stdout
,读者PIPE
是proc2
的stdin
。 proc1
will exit when proc2
exit and proc1
tries to write data to proc2
's stdin PIPE
. proc1
将在proc2
退出时退出, proc1
尝试将数据写入proc2
的stdin PIPE
。 because proc2
's stdin PIPE
is closed when proc2
exit proc2
的stdin PIPE
被关闭时proc2
退出 SIGPIPE
happen at proc1
because proc1
tries to write to closed proc2
's stdin PIPE
. SIGPIPE
发生在proc1
因为proc1
试图写入已关闭的proc2
的stdin PIPE
。 From my understanding, SIGPIPE
would happen and proc1
would exit, regardless of closing proc1
's stdout
. 根据我的理解,无论关闭
proc1
的stdout
, SIGPIPE
都会发生并且proc1
会退出。
What do I miss? 我错过了什么?
After reading the post from @unutbu's comment...... 阅读@ unutbu评论后的帖子 ......
I think the copied file descriptor( proc1.stdout
) is writer PIPE, not reader PIPE. 我认为复制的文件描述符(
proc1.stdout
)是writer PIPE,而不是reader PIPE。 thus, there are two writer PIPE and one reader PIPE connected one another. 因此,有两个作者PIPE和一个读者PIPE相互连接。
Therefore, SIGPIPE
will be generated when proc2
exit because proc2
is only one process which has reader PIPE(will be closed when proc2
exit). 因此,当
proc2
退出时将生成SIGPIPE
因为proc2
只是一个具有阅读器PIPE的进程(将在proc2
退出时关闭)。
However, the above post seems to say that there are two reader PIPEs by copying proc1.stdout
so SIGPIPE
won't be generated even after proc2
exit because there still is another reader PIPE open. 但是,上面的帖子似乎说通过复制
proc1.stdout
有两个读者proc1.stdout
所以即使在proc2
退出后也不会生成SIGPIPE
因为还有另一个读者PIPE打开。 the below is the part of post . 以下是帖子的一部分。
So by closing p1.stdout immediately, you ensure that the only remaining filehandle reading from dmesg stdout is the grep process, and if that process were to exit, dmesg receives a SIGPIPE.
因此,通过立即关闭p1.stdout,您可以确保从dmesg stdout读取的唯一剩余文件句柄是grep进程,如果该进程要退出,则dmesg会收到SIGPIPE。
I am not saying that the post is wrong but I just want to fix my understanding. 我并不是说帖子错了,但我只是想解决我的理解。 Thank you in advance.
先感谢您。
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
creates this a pipe between the parent process and proc1
: 在父进程和
proc1
之间创建一个管道:
| | | |
| parent |-<-----<-| proc1 |
| | ^ | |
|
p1.stdout
p1.stdout
is what the parent would read to obtain (stdout) output from proc1
. p1.stdout
是父p1.stdout
从proc1
获取(stdout)输出的内容。
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
connects a copy of the pipe from proc1 to proc2: 连接从proc1到proc2的管道副本:
| | | | | |
| parent |-<-----<-| proc1 |->----->-| proc2 |
| | | | | |
By calling p1.stdout.close()
, we close the parent processes's side of the pipe: 通过调用
p1.stdout.close()
,我们关闭管道的父进程端:
| | | | | |
| parent | <-| proc1 |->----->-| proc2 |
| | | | | |
Now when proc2
terminates, its side of the pipe is also closed: 现在,当
proc2
终止时,管道的一侧也会关闭:
| | | | | |
| parent | <-| proc1 |-> | proc2 |
| | | | | |
The next time proc1
tries to write to the pipe, a SIGPIPE signal is generated, which allows proc1
to terminate since it knows no one is listening on the other end of its pipes. proc1
下次尝试写入管道时,会生成一个SIGPIPE信号,该信号允许proc1
终止,因为它知道没有人正在监听其管道的另一端。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.