如何将SIGINT传递给孙辈(以及如何通过编程实现)

2024-09-28 21:49:41 发布

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

使用linux/bash/python3,我创建了一个孙子进程sleep 123。当我调用p.terminate()时,这会杀死子进程(init接管孙子进程sleep 123)。但是,在python解释器中,我仍然可以按Ctrl+C来杀死孙子。在

我的问题是1)python解释器如何可能将SIGINT发送给它的子代,而现在它是init的父代;2)我如何以编程方式杀死孙子。我试过p.send_signal(signal.SIGINT),玩stdin=PIPE等,但都没用。在

gnr@localhost: python3
Python 3.3.1
>>> from subprocess import PIPE, Popen
>>> p = Popen(['bash', '-c', '(sleep 123)'])

gnr@localhost: ps -AF | grep sleep
gnr 5081 5078 0 26526 1168 6 14:03 pts/26 00:00:00 bash -c (sleep 123)
gnr 5082 5081 0 25228 564  4 14:03 pts/26 00:00:00 sleep 123

>>> p.terminate()

gnr@localhost: ps -AF | grep sleep
gnr 5082    1 0 25228 564  4 14:03 pts/26 00:00:00 sleep 123   #init inherits

>>>        # hits Ctrl+C
keyboardInterrupt
>>>

gnr@localhost: ps -AF | grep sleep
#grandchild is dead

更新:我最后使用了pexpect(它为您处理了很多pty和termios的东西)。在


Tags: bashlocalhost进程initsleep解释器greppython3
2条回答

孙辈仍然将终端作为其标准输入,而不管是否进行任何重新绘制,因此在终端中按Ctrl-C会向它发送一个SIGINT。要自己动手,你需要知道孙子的PID。要获得它并不是一个简单的方法;您的子进程可能已经产生了十几个子进程,它们可能已经生成了更多的子进程,等等。根本不清楚哪一个将是“the”孙子

但是,您可以向前台组中的所有进程发送信号。在

os.kill(-os.getpgid(os.getpid()),signal.SIGINT)

当然,只有当Python本身连接到终端时,这才有效。在

在Linux上,向进程发送kill或terminate信号不会结束其子进程。它们成为孤立的,并被init系统进程采用。在

您可以使用psutil包。你可以这样做:

from subprocess import Popen
import psutil

proc = Popen(['bash', '-c', '(sleep 123)'])
parent = psutil.Process(proc.pid)
for child in parent.children(recursive=True):
    child.terminate()

parent.terminate()

相关问题 更多 >