GNU/Linux >> Linux Esercitazione >  >> Linux

Come uccidere un processo figlio python creato con subprocess.check_output() quando il genitore muore?

Sì, puoi ottenere questo risultato con due metodi. Entrambi richiedono l'uso di Popen invece di check_output . Il primo è un metodo più semplice, che utilizza try..finally, come segue:

from contextlib import contextmanager

@contextmanager
def run_and_terminate_process(*args, **kwargs):
try:
    p = subprocess.Popen(*args, **kwargs)
    yield p        
finally:
    p.terminate() # send sigterm, or ...
    p.kill()      # send sigkill

def main():
    with run_and_terminate_process(args) as running_proc:
        # Your code here, such as running_proc.stdout.readline()

Questo rileverà sigint (interruzione della tastiera) e sigterm, ma non sigkill (se interrompi lo script con -9).

L'altro metodo è un po' più complesso e utilizza prctl PR_SET_PDEATHSIG di ctypes. Il sistema invierà un segnale al bambino una volta che il genitore esce per qualsiasi motivo (anche sigkill).

import signal
import ctypes
libc = ctypes.CDLL("libc.so.6")
def set_pdeathsig(sig = signal.SIGTERM):
    def callable():
        return libc.prctl(1, sig)
    return callable
p = subprocess.Popen(args, preexec_fn = set_pdeathsig(signal.SIGTERM))

Il tuo problema è con l'utilizzo di subprocess.check_output - hai ragione, non puoi ottenere il PID figlio usando quell'interfaccia. Usa invece Popen:

proc = subprocess.Popen(["ls", "-l"], stdout=PIPE, stderr=PIPE)

# Here you can get the PID
global child_pid
child_pid = proc.pid

# Now we can wait for the child to complete
(output, error) = proc.communicate()

if error:
    print "error:", error

print "output:", output

Per assicurarti di uccidere il bambino all'uscita:

import os
import signal
def kill_child():
    if child_pid is None:
        pass
    else:
        os.kill(child_pid, signal.SIGTERM)

import atexit
atexit.register(kill_child)

Linux
  1. Come Kali si occupa dell'imminente Python 2 End-of-Life

  2. Come far morire il processo figlio dopo che il genitore è uscito?

  3. Come terminare un sottoprocesso Python avviato con shell=True

  4. Come uccidere un processo figlio dopo un determinato timeout in Bash?

  5. Come uccidere tutti i processi con un determinato nome parziale?

Come trovare l'ID di processo di un programma e ucciderlo [Suggerimento rapido]

Perché il Pgid dei processi figlio non è il Pid del genitore?

Come uccidere o terminare un processo Linux:la guida definitiva

Come ottenere il PID in base al nome del processo?

Come uccidere lo script Python con lo script bash

Come uccidere un processo che non muore mai?