San*_*Kim 4 python linux subprocess pipe 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))
Run Code Online (Sandbox Code Playgroud)
但是,我并不清楚。请修正我的理解。
SIGPIPE当 aPIPE尝试写入 closed时发生PIPE。PIPE是proc1的stdout和读者PIPE是proc2的stdin。proc1退出时将退出proc2并proc1尝试将数据写入proc2's stdin PIPE。因为
proc2的stdin PIPE是,当关闭proc2退出SIGPIPE发生在proc1因为proc1尝试写入关闭proc2的stdin PIPE.从我的理解,SIGPIPE总会发生,proc1将退出不管收,proc1的stdout。
我想念什么?
阅读@unutbu 评论中的帖子后......
我认为复制的文件描述符(proc1.stdout)是写入器 PIPE,而不是读取器 PIPE。因此,有两个写入器 PIPE 和一个读取器 PIPE 相互连接。
因此,退出SIGPIPE时会生成,proc2因为proc2只有一个进程有读取器 PIPE(proc2退出时将关闭)。
但是,上面的帖子似乎是说通过复制有两个阅读器PIPE,proc1.stdout因此SIGPIPE即使proc2退出后也不会生成,因为还有另一个阅读器PIPE打开。以下是帖子的部分。
因此,通过立即关闭 p1.stdout,您可以确保从 dmesg stdout 读取的唯一剩余文件句柄是 grep 进程,如果该进程退出,dmesg 会收到一个 SIGPIPE。
我并不是说该帖子是错误的,但我只是想纠正我的理解。先感谢您。
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
在父进程和proc1以下进程之间创建一个管道:
| | | |
| parent |-<-----<-| proc1 |
| | ^ | |
|
p1.stdout
Run Code Online (Sandbox Code Playgroud)
p1.stdout是父级从proc1.
proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
Run Code Online (Sandbox Code Playgroud)
将管道的副本从 proc1 连接到 proc2:
| | | | | |
| parent |-<-----<-| proc1 |->----->-| proc2 |
| | | | | |
Run Code Online (Sandbox Code Playgroud)
通过调用p1.stdout.close(),我们关闭了管道的父进程一侧:
| | | | | |
| parent | <-| proc1 |->----->-| proc2 |
| | | | | |
Run Code Online (Sandbox Code Playgroud)
现在,当proc2终止时,它的管道一侧也关闭了:
| | | | | |
| parent | <-| proc1 |-> | proc2 |
| | | | | |
Run Code Online (Sandbox Code Playgroud)
下一次proc1尝试写入管道时,会生成一个 SIGPIPE 信号,该信号允许proc1终止,因为它知道没有人在其管道的另一端监听。
| 归档时间: |
|
| 查看次数: |
694 次 |
| 最近记录: |