Python子进程.Popen PIPE和SIGPIPE [英] Python subprocess.Popen PIPE and SIGPIPE

查看:171
本文介绍了Python子进程.Popen PIPE和SIGPIPE的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我浏览帖子时,我在下面的此处遇到了这个示例,这就是说需要proc1.stdout.close()调用proc1的适当出口,生成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.

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.

  1. SIGPIPE是在PIPE尝试写入已关闭的PIPE时发生的.
  2. 写入器PIPEproc1stdout,读取器PIPEproc2stdin.
  3. proc1将在proc2退出并且proc1尝试将数据写入proc2stdin PIPE时退出. 因为
    • proc2stdin PIPEproc2退出时关闭
    • SIGPIPE发生在proc1,因为proc1试图写入封闭的proc2stdin PIPE.
  1. SIGPIPE occurs when a PIPE tries to write to closed PIPE.
  2. Writer PIPE is proc1's stdout and reader PIPE is proc2's stdin.
  3. proc1 will exit when proc2 exit and proc1 tries to write data to proc2's stdin PIPE. because
    • proc2's stdin PIPE is closed when proc2 exit
    • SIGPIPE happen at proc1 because proc1 tries to write to closed proc2's stdin PIPE.

据我了解,无论关闭proc1stdout,都会发生SIGPIPEproc1退出.

From my understanding, SIGPIPE would happen and proc1 would exit, regardless of closing proc1's stdout.

我想念什么?

从@unutbu的评论中阅读帖子后……

After reading the post from @unutbu's comment......

我认为复制的文件描述符(proc1.stdout)是写程序PIPE,而不是读程序PIPE.因此,有两个写入器PIPE和一个读取器PIPE相互连接.

I think the copied file descriptor(proc1.stdout) is writer PIPE, not reader PIPE. thus, there are two writer PIPE and one reader PIPE connected one another.

因此,proc2退出时将生成SIGPIPE,因为proc2只是一个具有读取器PIPE的进程(proc2退出时将关闭).

Therefore, SIGPIPE will be generated when proc2 exit because proc2 is only one process which has reader PIPE(will be closed when proc2 exit).

但是,上面的帖子似乎说,通过复制proc1.stdout,有两个读取器PIPE,因此SIGPIPE proc2退出后也不会生成,因为仍然有另一个读取器PIPE打开.以下是帖子的一部分.

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. the below is the part of post.

因此,通过立即关闭p1.stdout,您可以确保唯一 从dmesg stdout读取的剩余文件句柄是grep进程, 如果该过程将退出,则dmesg会收到SIGPIPE.

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.

我并不是说帖子是错误的,但我只是想修正我的理解.预先谢谢你.

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)

在父进程和proc1之间创建一个管道:

creates this a pipe between the parent process and proc1:

|        |         |       |
| parent |-<-----<-| proc1 |                   
|        | ^       |       |
           |                     
       p1.stdout   

p1.stdout是父级将读取以从proc1获得(stdout)输出的内容.

p1.stdout is what the parent would read to obtain (stdout) output from proc1.

proc2 = subprocess.Popen(['grep', 'python'], stdin=proc1.stdout,
                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)

将管道的副本从proc1连接到proc2:

connects a copy of the pipe from proc1 to proc2:

|        |         |       |         |       |
| parent |-<-----<-| proc1 |->----->-| proc2 | 
|        |         |       |         |       |

通过调用p1.stdout.close(),我们关闭了父进程的管道一侧:

By calling p1.stdout.close(), we close the parent processes's side of the pipe:

|        |         |       |         |       |
| parent |       <-| proc1 |->----->-| proc2 | 
|        |         |       |         |       |

现在,当proc2终止时,管道的一侧也将关闭:

Now when proc2 terminates, its side of the pipe is also closed:

|        |         |       |         |       |
| parent |       <-| proc1 |->       | proc2 | 
|        |         |       |         |       |

下次proc1尝试写入管道时,将生成SIGPIPE信号, 允许proc1终止,因为它不知道有人在其管道的另一端进行监听.

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.

这篇关于Python子进程.Popen PIPE和SIGPIPE的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆