GNU/Linux >> Tutoriales Linux >  >> Linux

¿Cómo eliminar un proceso secundario de Python creado con subprocess.check_output() cuando el padre muere?

Sí, puede lograr esto por dos métodos. Ambos requieren que uses Popen en lugar de check_output . El primero es un método más simple, usando try..finally, como sigue:

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()

Esto capturará sigint (interrupción del teclado) y sigterm, pero no sigkill (si elimina su secuencia de comandos con -9).

El otro método es un poco más complejo y usa prctl PR_SET_PDEATHSIG de ctypes. El sistema enviará una señal al niño una vez que el padre salga por cualquier motivo (incluso 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))

Su problema es con el uso de subprocess.check_output - tiene razón, no puede obtener el PID secundario usando esa interfaz. Usa Popen en su lugar:

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

Para asegurarte de matar al niño al salir:

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. Cómo lidia Kali con el próximo fin de vida de Python 2

  2. ¿Cómo hacer que el proceso hijo muera después de que el padre salga?

  3. Cómo finalizar un subproceso de python iniciado con shell=True

  4. ¿Cómo eliminar un proceso secundario después de un tiempo de espera determinado en Bash?

  5. ¿Cómo matar todos los procesos con un nombre parcial dado?

Cómo encontrar el ID de proceso de un programa y eliminarlo [Consejo rápido]

¿Por qué el Pgid de los procesos secundarios no es el Pid del padre?

¿Cómo matar un proceso cuyo padre es Init?

Cómo matar o terminar un proceso de Linux:la guía definitiva

¿Cómo obtener la identificación del proceso para eliminar un proceso nohup?

¿Cómo obtener PID por nombre de proceso?