python 杀死子进程_Python:当父异常终止时,如何杀死子进程?
小編典典
呵呵,我昨天自己在研究這個!假設您無法更改子程序:
在Linux上,prctl(PR_SET_PDEATHSIG,...)可能是唯一可靠的選擇。(如果絕對有必要終止子進程,那么您可能希望將終止信號設置為SIGKILL而不是SIGTERM;鏈接到的代碼使用SIGTERM,但是子級確實可以選擇忽略SIGTERM。
)
在Windows上,最可靠的選擇是使用Job對象。想法是創建一個“作業”(一種用于流程的容器),然后將子流程放入作業中,并設置魔術選項,指出“當沒有人握住該作業的“手柄”時,然后殺死其中的進程”。默認情況下,作業的唯一“句柄”是父進程持有的句柄,并且當父進程死掉時,操作系統將遍歷并關閉其所有句柄,然后注意這意味著沒有用于工作。因此,它會按要求殺死孩子。包含使用該win32api模塊執行此操作的示例代碼。該代碼使用CreateProcess發射子,而不是subprocess.Popen。原因是他們需要為生成的子項獲取一個“進程句柄”,并CreateProcess默認將其返回。如果您愿意使用subprocess.Popen,那么這是該答案中代碼的(未經測試的)副本,它使用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)
從技術上講,這里有一個很小的比賽條件,以防孩子在Popen和OpenProcess呼叫之間死亡,您可以決定是否要擔心這一點。
使用作業對象的一個??缺點是,在Vista或Win7上運行時,如果從Windows
Shell啟動程序(即,通過單擊圖標),則可能已經分配了一個作業對象并嘗試創建一個作業對象。新的作業對象將失敗。Win8可以解決此問題(通過允許嵌套作業對象),或者如果您的程序是從命令行運行的,那么應該可以。
如果您 可以
修改子級(例如,像使用時一樣multiprocessing),那么最好的選擇可能是以某種方式將父級的PID傳遞給子級(例如,作為命令行參數,或者在的args=參數中multiprocessing.Process),然后:
在POSIX上:在子級中生成一個os.getppid()偶爾會調用的線程,如果返回值停止匹配從父級傳入的pid,則調用os._exit()。(這種方法可移植到包括OS
X在內的所有Unix上,而prctl竅門是特定于Linux的。)
在Windows上:在使用OpenProcess和的子代中產生一個線程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)
這避免了我提到的作業對象的任何可能的問題。
如果您想真正確定,那么可以組合所有這些解決方案。
希望有幫助!
2020-06-02
總結
以上是生活随笔為你收集整理的python 杀死子进程_Python:当父异常终止时,如何杀死子进程?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 投资性价比夏普比率是什么意思
- 下一篇: 石墨烯电池股票龙头股 石墨烯电池股票有哪