Popen启动killswitch.exe产生双进程,如何实现单进程或关闭全部进程?
解决Popen启动killswitch.exe残留进程的问题
问题根源
你碰到的双进程残留,多半是killswitch.exe自身启动了子进程,或者Windows系统下进程创建的特性导致——Popen返回的只是父进程句柄,单独杀父进程的话,子进程会变成孤儿进程继续运行。
可行解决办法
1. 从exe本身入手:改成单进程运行
如果能修改killswitch.exe的代码,直接做单实例绑定:启动时检查是否已有绑定当前主线程PID的自身实例,避免额外生成子进程。这是最彻底的方案,从根源上杜绝多进程问题。
2. 用psutil追踪并杀死所有关联进程
要是改不了exe,就用psutil库精准清理当前实例的所有关联进程,不会误杀其他killswitch实例:
首先安装psutil:
pip install psutil
然后用下面的代码处理:
import psutil from subprocess import Popen # 启动killswitch killSwitch = Popen(['killswitch.exe', str(pid)]) # 正常关闭程序时调用这个清理函数 def cleanup_killswitch(): try: # 获取当前启动的killswitch父进程 parent_proc = psutil.Process(killSwitch.pid) # 递归获取它的所有子进程 all_child_procs = parent_proc.children(recursive=True) # 先杀子进程,再杀父进程 for proc in all_child_procs: proc.kill() parent_proc.kill() # 等待进程彻底退出,超时3秒就放弃 parent_proc.wait(timeout=3) except (psutil.NoSuchProcess, psutil.AccessDenied, TimeoutError): # 进程可能已经自己退出了,直接忽略错误 pass
这个方法只会处理你当前启动的这个killswitch实例的所有关联进程,完全不会影响其他运行中的killswitch。
3. 用Windows进程组特性批量终止
通过Popen的creationflags参数,把killswitch及其子进程归为同一个进程组,然后发送中断信号终止整个组:
from subprocess import Popen, CREATE_NEW_PROCESS_GROUP import signal # 启动时指定创建新进程组 killSwitch = Popen(['killswitch.exe', str(pid)], creationflags=CREATE_NEW_PROCESS_GROUP) # 关闭时发送CTRL_BREAK信号终止整个进程组 killSwitch.send_signal(signal.CTRL_BREAK_EVENT) killSwitch.wait()
注意:这个方法需要killswitch.exe能响应CTRL_BREAK信号,如果exe没处理这个信号,可能不会生效,得实际测试一下。
内容的提问来源于stack exchange,提问作者Paul
相关产品推荐
相关产品推荐

