Python子流程.Popen管道和信号管道

2024-09-25 04:26:20 发布

您现在位置:Python中文网/ 问答频道 /正文

当我浏览帖子时,我在here上遇到了下面的例子,它说需要调用proc1.stdout.close()来适当退出{},生成{}。在

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))

然而,我对此并不清楚。请纠正我的理解。在

  1. SIGPIPEPIPE试图写入已关闭的PIPE时发生。在
  2. Writer PIPEproc1stdout,读卡器{}是{}的stdin。在
  3. ^当proc2退出并且proc1试图将数据写入proc2的{}时,{}将退出。 因为
    • proc2stdin PIPEproc2退出时关闭
    • SIGPIPE发生在proc1处,因为proc1试图写入关闭的proc2的{}。在

根据我的理解,SIGPIPE会发生,proc1将退出,而不管{}的{}关闭。在

我错过了什么?在


编辑

在阅读了@unutbu评论中的post之后。。。。。。在

我认为复制的文件描述符(proc1.stdout)是writer管道,而不是reader管道。因此,有两个写入管道和一个读取管道彼此连接。在

因此,proc2退出时将生成SIGPIPE,因为proc2只是一个有读卡器管道的进程(当proc2退出时将关闭)。在

但是,上面的post似乎说明通过复制proc1.stdout有两个读卡器管道,因此即使在proc2退出后也不会生成{},因为还有另一个读卡器管道打开。下面是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.

我不是说post是错的,但我只是想修正我的理解。提前谢谢你。在


Tags: close管道stdinstdoutoutpostgrepsubprocess
1条回答
网友
1楼 · 发布于 2024-09-25 04:26:20
proc1 = subprocess.Popen(['ps', 'cax'], stdout=subprocess.PIPE)

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

^{pr2}$

p1.stdout是父进程将从proc1获取(stdout)输出的内容。在

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

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

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

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

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

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

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

下次proc1试图写入管道时,会生成一个SIGPIPE信号, 它允许proc1终止,因为它知道没有人监听其管道的另一端。在

相关问题 更多 >