[英]Kill Child Process if Parent is killed in Python
我正在从 python 脚本生成 5 个不同的进程,如下所示:
p = multiprocessing.Process(target=some_method,args=(arg,))
p.start()
我的问题是,当父进程(主脚本)以某种方式被杀死时,子进程继续运行。
当父进程被杀死时,有没有办法杀死像这样产生的子进程?
编辑:我正在尝试这个:
p = multiprocessing.Process(target=client.start,args=(self.query_interval,))
p.start()
atexit.register(p.terminate)
但这似乎不起作用
我自己也遇到过同样的问题,我有以下解决方案:
在调用p.start()
之前,您可以设置p.daemon=True
。 然后正如这里提到的python.org 多处理
当一个进程退出时,它会尝试终止其所有守护进程。
孩子不会收到父母死亡的通知,它只会以另一种方式工作。
但是,当一个进程终止时,它的所有文件描述符都将关闭。 如果管道的另一端选择了要读取的管道,则会通知管道的另一端。
因此,您的父母可以在生成进程之前创建一个管道(或者实际上,您可以将 stdin 设置为管道),而孩子可以选择它进行阅读。 当父端关闭时,它将报告准备好阅读。 这需要您的孩子运行主循环,或者至少定期调用选择。 如果你不想那样做,你需要一些管理器进程来做,但是当那个进程被杀死时,事情又会崩溃。
如果您有权访问父 pid,则可以使用这样的方法
import os
import sys
import psutil
def kill_child_proc(ppid):
for process in psutil.process_iter():
_ppid = process.ppid()
if _ppid == ppid:
_pid = process.pid
if sys.platform == 'win32':
process.terminate()
else:
os.system('kill -9 {0}'.format(_pid))
kill_child_proc(<parent_pid>)
我的情况是使用Queue
对象与子进程通信。 无论出于何种原因,已接受答案中建议的daemon
标志不起作用。 这是一个最小的例子,说明在这种情况下如何让孩子们优雅地死去。
主要思想是每隔一秒左右暂停子工作执行并检查父进程是否还活着。 如果它不存在,我们关闭队列并退出。
请注意,如果使用SIGKILL
杀死主进程,这也有效
import ctypes, sys
import multiprocessing as mp
worker_queue = mp.Queue(maxsize=10)
# flag to communicate the parent's death to all children
alive = mp.Value(ctypes.c_bool, lock=False)
alive.value = True
def worker():
while True:
# fake work
data = 99.99
# submit finished work to parent, while checking if parent has died
queued = False
while not queued:
# note here we do not block indefinitely, so we can check if parent died
try:
worker_queue.put(data, block=True, timeout=1.0)
queued = True
except: pass
# check if parent process is alive still
par_alive = mp.parent_process().is_alive()
if not (par_alive and alive.value):
# for some reason par_alive is only False for one of the children;
# notify the others that the parent has died
alive.value = False
# appears we need to close the queue before sys.exit will work
worker_queue.close()
# for more dramatic shutdown, could try killing child process;
# wp.current_process().kill() does not work, though you could try
# calling os.kill directly with the child PID
sys.exit(1)
# launch worker processes
for i in range(4):
child = mp.Process(target=worker)
child.start()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.