[英]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.