python 杀死子进程_Python:当父异常终止时,如何杀死子进程?
小編典典
呵呵,我昨天自己在研究這個(gè)!假設(shè)您無法更改子程序:
在Linux上,prctl(PR_SET_PDEATHSIG,...)可能是唯一可靠的選擇。(如果絕對(duì)有必要終止子進(jìn)程,那么您可能希望將終止信號(hào)設(shè)置為SIGKILL而不是SIGTERM;鏈接到的代碼使用SIGTERM,但是子級(jí)確實(shí)可以選擇忽略SIGTERM。
)
在Windows上,最可靠的選擇是使用Job對(duì)象。想法是創(chuàng)建一個(gè)“作業(yè)”(一種用于流程的容器),然后將子流程放入作業(yè)中,并設(shè)置魔術(shù)選項(xiàng),指出“當(dāng)沒有人握住該作業(yè)的“手柄”時(shí),然后殺死其中的進(jìn)程”。默認(rèn)情況下,作業(yè)的唯一“句柄”是父進(jìn)程持有的句柄,并且當(dāng)父進(jìn)程死掉時(shí),操作系統(tǒng)將遍歷并關(guān)閉其所有句柄,然后注意這意味著沒有用于工作。因此,它會(huì)按要求殺死孩子。包含使用該win32api模塊執(zhí)行此操作的示例代碼。該代碼使用CreateProcess發(fā)射子,而不是subprocess.Popen。原因是他們需要為生成的子項(xiàng)獲取一個(gè)“進(jìn)程句柄”,并CreateProcess默認(rèn)將其返回。如果您愿意使用subprocess.Popen,那么這是該答案中代碼的(未經(jīng)測(cè)試的)副本,它使用subprocess.Popen和OpenProcess代替CreateProcess:
import subprocess
import win32api
import win32con
import win32job
hJob = win32job.CreateJobObject(None, "")
extended_info = win32job.QueryInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation)
extended_info['BasicLimitInformation']['LimitFlags'] = win32job.JOB_OBJECT_LIMIT_KILL_ON_JOB_CLOSE
win32job.SetInformationJobObject(hJob, win32job.JobObjectExtendedLimitInformation, extended_info)
child = subprocess.Popen(...)
# Convert process id to process handle:
perms = win32con.PROCESS_TERMINATE | win32con.PROCESS_SET_QUOTA
hProcess = win32api.OpenProcess(perms, False, child.pid)
win32job.AssignProcessToJobObject(hJob, hProcess)
從技術(shù)上講,這里有一個(gè)很小的比賽條件,以防孩子在Popen和OpenProcess呼叫之間死亡,您可以決定是否要擔(dān)心這一點(diǎn)。
使用作業(yè)對(duì)象的一個(gè)??缺點(diǎn)是,在Vista或Win7上運(yùn)行時(shí),如果從Windows
Shell啟動(dòng)程序(即,通過單擊圖標(biāo)),則可能已經(jīng)分配了一個(gè)作業(yè)對(duì)象并嘗試創(chuàng)建一個(gè)作業(yè)對(duì)象。新的作業(yè)對(duì)象將失敗。Win8可以解決此問題(通過允許嵌套作業(yè)對(duì)象),或者如果您的程序是從命令行運(yùn)行的,那么應(yīng)該可以。
如果您 可以
修改子級(jí)(例如,像使用時(shí)一樣multiprocessing),那么最好的選擇可能是以某種方式將父級(jí)的PID傳遞給子級(jí)(例如,作為命令行參數(shù),或者在的args=參數(shù)中multiprocessing.Process),然后:
在POSIX上:在子級(jí)中生成一個(gè)os.getppid()偶爾會(huì)調(diào)用的線程,如果返回值停止匹配從父級(jí)傳入的pid,則調(diào)用os._exit()。(這種方法可移植到包括OS
X在內(nèi)的所有Unix上,而prctl竅門是特定于Linux的。)
在Windows上:在使用OpenProcess和的子代中產(chǎn)生一個(gè)線程os.waitpid。使用ctypes的示例:
from ctypes import WinDLL, WinError
from ctypes.wintypes import DWORD, BOOL, HANDLE
# Magic value from http://msdn.microsoft.com/en-us/library/ms684880.aspx
SYNCHRONIZE = 0x00100000
kernel32 = WinDLL("kernel32.dll")
kernel32.OpenProcess.argtypes = (DWORD, BOOL, DWORD)
kernel32.OpenProcess.restype = HANDLE
parent_handle = kernel32.OpenProcess(SYNCHRONIZE, False, parent_pid)
# Block until parent exits
os.waitpid(parent_handle, 0)
os._exit(0)
這避免了我提到的作業(yè)對(duì)象的任何可能的問題。
如果您想真正確定,那么可以組合所有這些解決方案。
希望有幫助!
2020-06-02
總結(jié)
以上是生活随笔為你收集整理的python 杀死子进程_Python:当父异常终止时,如何杀死子进程?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 投资性价比夏普比率是什么意思
- 下一篇: websocket python爬虫_p