如何终止Python通过sudo启动的C++可执行子进程?
问题解决:Python调用sudo启动的C++进程无法被SIGINT终止
问题根源:你通过sudo启动Trench.out时,subprocess.Popen返回的PID是sudo进程的PID,而非目标C++程序的PID。直接给sudo进程发送SIGINT,默认情况下sudo不会将信号传递给子进程,导致Trench.out继续后台运行。
以下是无需修改C++源码的解决办法:
方法一:定位真实子进程发送信号
借助psutil库遍历进程树,找到sudo进程下的Trench.out子进程,再发送SIGINT:
import os import subprocess import signal import time import psutil def trench(): return subprocess.Popen( ['sudo', './Trench.out'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, ) trench_display = trench() time.sleep(5) # 遍历sudo进程的子进程,找到Trench.out sudo_proc = psutil.Process(trench_display.pid) for child in sudo_proc.children(recursive=True): if child.name() == 'Trench.out': child.send_signal(signal.SIGINT) # 等待sudo进程退出 trench_display.wait()
方法二:用pkill直接匹配进程名
直接通过sudo pkill命令给Trench.out发送SIGINT,无需跟踪PID:
import subprocess import time def trench(): return subprocess.Popen( ['sudo', './Trench.out'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, ) trench_display = trench() time.sleep(5) # -2对应SIGINT,和Ctrl+C发送的信号一致 subprocess.run(['sudo', 'pkill', '-2', 'Trench.out']) trench_display.wait()
方法三:创建进程组并杀死整个组
启动进程时开启新会话,让sudo和Trench.out同属一个进程组,然后杀死整个组:
import os import subprocess import signal import time def trench(): return subprocess.Popen( ['sudo', './Trench.out'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT, start_new_session=True # 创建新进程组 ) trench_display = trench() time.sleep(5) # 杀死整个进程组 os.killpg(os.getpgid(trench_display.pid), signal.SIGINT) trench_display.wait()
内容的提问来源于stack exchange,提问作者N00B_141
相关产品推荐
相关产品推荐

