Su Windows, subprocess.Popen.terminate
chiamate win32 TerminalProcess
. Tuttavia, il comportamento che vedo è che i processi figlio del processo che sto cercando di terminare sono ancora in esecuzione. Perché? Come posso garantire che tutti i processi figli avviati dal processo vengano uccisi?: eliminazione di processi figlio in Windows
risposta
Utilizzando psutil:
import psutil, os
def kill_proc_tree(pid, including_parent=True):
parent = psutil.Process(pid)
children = parent.children(recursive=True)
for child in children:
child.kill()
gone, still_alive = psutil.wait_procs(children, timeout=5)
if including_parent:
parent.kill()
parent.wait(5)
me = os.getpid()
kill_proc_tree(me)
Sembra che il codice uccida solo i bambini di primo livello, non i nipoti, ecc. Potrebbe essere un problema se si stanno avviando strumenti di build o file .bat/.cmd con cmd.exe.A meno che get_children() significhi anche i nipoti? – Macke
Esattamente. Per includere i nipoti devi specificare l'opzione 'ricorsiva' come in parent.get_children (ricorsiva = True) –
Questa è una vecchia risposta, ma era esattamente quello che stavo cercando: un modo multipiattaforma per uccidere tutti i processi figli. Tutte le altre risposte che sono apparse su Google affermano che non può essere fatto. Grazie per psutil! – Gilead
Questa è una cosa difficile da fare. Windows non archivia effettivamente una struttura del processo nello spazio del processo. Né è possibile interrompere un processo e specificare che anche i bambini dovrebbero morire.
Un modo per aggirare questo è usare taskkill e dirgli di incastrare l'intero albero.
Un altro modo per farlo (supponendo che si stanno deponendo le uova il processo di livello superiore) è quello di utilizzare un modulo che è stato sviluppato con questo genere di cose in mente: http://benjamin.smedbergs.us/blog/tag/killableprocess/
Per fare questo modo generico per te , devi passare un po 'di tempo a costruire la lista all'indietro. Cioè, un processo memorizza i puntatori al suo PARENT, ma i genitori sembrano non memorizzare informazioni sui bambini.
Quindi è necessario esaminare tutti i processi nel sistema (che in realtà non è così difficile), quindi collegare manualmente i punti manualmente osservando il campo del processo principale. Quindi, seleziona l'albero a cui sei interessato e cammina tutto, uccidendo ogni nodo a turno uno per uno.
Si noti che Windows non aggiorna il puntatore padre di un figlio quando il genitore muore, quindi potrebbero esserci degli spazi nella struttura. Non sono a conoscenza di nulla che tu possa fare riguardo a quelli.
Mettere i bambini in un NT Job object, allora si può uccidere tutti i bambini
Gli oggetti di lavoro sembrano il modo giusto per affrontare questo problema; peccato che questo non è integrato con il modulo subprocess. –
Utilizzare taskkill
con la bandiera /T
p = subprocess.Popen(...)
<wait>
subprocess.call(['taskkill', '/F', '/T', '/PID', str(p.pid)])
Le bandiere a taskkill ha i seguenti documenti:
TASKKILL [/S system [/U username [/P [password]]]]
{ [/FI filter] [/PID processid | /IM imagename] } [/T] [/F]
/S system Specifies the remote system to connect to.
/U [domain\]user Specifies the user context under which the
command should execute.
/P [password] Specifies the password for the given user
context. Prompts for input if omitted.
/FI filter Applies a filter to select a set of tasks.
Allows "*" to be used. ex. imagename eq acme*
/PID processid Specifies the PID of the process to be terminated.
Use TaskList to get the PID.
/IM imagename Specifies the image name of the process
to be terminated. Wildcard '*' can be used
to specify all tasks or image names.
/T Terminates the specified process and any
child processes which were started by it.
/F Specifies to forcefully terminate the process(es).
/? Displays this help message.
Oppure a piedi l'albero processo utilizzando comtypes e Win32API:
def killsubprocesses(parent_pid):
'''kill parent and all subprocess using COM/WMI and the win32api'''
log = logging.getLogger('killprocesses')
try:
import comtypes.client
except ImportError:
log.debug("comtypes not present, not killing subprocesses")
return
logging.getLogger('comtypes').setLevel(logging.INFO)
log.debug('Querying process tree...')
# get pid and subprocess pids for all alive processes
WMI = comtypes.client.CoGetObject('winmgmts:')
processes = WMI.InstancesOf('Win32_Process')
subprocess_pids = {} # parent pid -> list of child pids
for process in processes:
pid = process.Properties_('ProcessID').Value
parent = process.Properties_('ParentProcessId').Value
log.trace("process %i's parent is: %s" % (pid, parent))
subprocess_pids.setdefault(parent, []).append(pid)
subprocess_pids.setdefault(pid, [])
# find which we need to kill
log.debug('Determining subprocesses for pid %i...' % parent_pid)
processes_to_kill = []
parent_processes = [parent_pid]
while parent_processes:
current_pid = parent_processes.pop()
subps = subprocess_pids[current_pid]
log.debug("process %i children are: %s" % (current_pid, subps))
parent_processes.extend(subps)
processes_to_kill.extend(subps)
# kill the subprocess tree
if processes_to_kill:
log.info('Process pid %i spawned %i subprocesses, terminating them...' %
(parent_pid, len(processes_to_kill)))
else:
log.debug('Process pid %i had no subprocesses.' % parent_pid)
import ctypes
kernel32 = ctypes.windll.kernel32
for pid in processes_to_kill:
hProcess = kernel32.OpenProcess(PROCESS_TERMINATE, FALSE, pid)
if not hProcess:
log.warning('Unable to open process pid %i for termination' % pid)
else:
log.debug('Terminating pid %i' % pid)
kernel32.TerminateProcess(hProcess, 3)
kernel32.CloseHandle(hProcess)
Grazie per questo. – Speakeasys
Ecco esempio di codice per il metodo oggetto del lavoro, ma invece di subprocess
usa win32api.CreateProcess
import win32process
import win32job
startup = win32process.STARTUPINFO()
(hProcess, hThread, processId, threadId) = win32process.CreateProcess(None, command, None, None, True, win32process.CREATE_BREAKAWAY_FROM_JOB, None, None, startup)
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)
win32job.AssignProcessToJobObject(hJob, hProcess)
+1: sembra la soluzione più efficace che funziona anche se il processo padre si è bloccato. Ecco [la spiegazione su come funziona] (http://stackoverflow.com/a/23587108/4279) – jfs
Ho avuto lo stesso problema e semplicemente uccidere processo tramite comando di Windows con opzione per l'uccisione di bambini "/ T"
def kill_command_windows(pid):
'''Run command via subprocess'''
dev_null = open(os.devnull, 'w')
command = ['TASKKILL', '/F', '/T', '/PID', str(pid)]
proc = subprocess.Popen(command, stdin=dev_null, stdout=sys.stdout, stderr=sys.stderr)
Stavo tentando di uccidere un processo di build Gradle avviato con 'subprocess.Popen()'. Un semplice 'process.terminate()' o 'process.kill()' non ha funzionato su Windows 7, e nemmeno l'opzione 'psutils' in precedenza, ma così è stato. –
- 1. Eliminazione dei processi generati quando esce grunt
- 2. In attesa di processi di grandchild in windows
- 3. supervisione arrestando i processi figlio
- 4. fork() processi figlio e genitore
- 5. Elaborazione di processi figlio da Perl
- 6. Condivisione di porte Mach con processi figlio
- 7. Come limitare i processi figlio di Jenkins?
- 8. Inserimento completo/aggiornamento/eliminazione di entità figlio in Entity Framework
- 9. fork() e wait() con due processi figlio
- 10. Golang: I processi figlio diventano Zombi
- 11. Entity Framework 5 - Eliminazione figlio record
- 12. Come eliminare tutti i processi figlio all'uscita?
- 13. Eliminazione dei privilegi in C++ su Windows
- 14. Come fork() n processi figlio correttamente in C?
- 15. Recupero di un elenco completo di processi Windows in C
- 16. spawning I processi figlio node.js risultano nei processi zombi su cloud fonderia
- 17. Discussioni/Confronto dei processi su Linux/Windows
- 18. Come posso passare un socket dai processi padre a figlio
- 19. I processi figlio Node.JS vengono uccisi quando il genitore muore
- 20. fork() e STDOUT/STDERR alla console da processi figlio
- 21. Processi Windows nel kernel vs sistema
- 22. Come escludere determinati processi figlio da eseguire con valgrind?
- 23. Passare PID dall'elenco attività e processi di eliminazione con l'elenco attività
- 24. Node.js figlio processi e pipe - OSX vs Ubuntu
- 25. Attesa del genitore per tutti i processi figlio
- 26. MPI Spawn: processo radice non comunica ai processi figlio
- 27. La deposizione delle uova e in attesa di processi figlio in Python
- 28. Elencare i processi in esecuzione su Windows a 64 bit
- 29. Utilizzo di un Kinect per Windows per due processi paralleli
- 30. Come utilizzare Trap in modo affidabile utilizzando Bash in esecuzione processi figlio in primo piano
Quale versione di Python e Windows? –
Qui ci sono 2 opzioni 1. Usa questo exe come sottoprocesso che uccide gli alberi del processo per te: http://www.latenighthacking.com/projects/2002/kill/ 2. Converti il seguente codice C in Python con ctypes: http: //stackoverflow.com/questions/1173342/terminate-a-process-tree-c-for-windows – Unknown