GNU/Linux >> Znalost Linux >  >> Linux

Jak zabít podřízený proces pythonu vytvořený pomocí subprocess.check_output(), když rodič zemře?

Ano, můžete toho dosáhnout dvěma způsoby. Oba vyžadují, abyste použili Popen místo check_output . První je jednodušší metoda, pomocí try..konečně, takto:

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

To zachytí sigint (přerušení klávesnice) a sigterm, ale ne sigkill (pokud skript zabijete s -9).

Druhá metoda je o něco složitější a používá prctl PR_SET_PDEATHSIG ctypes. Jakmile rodič z jakéhokoli důvodu (dokonce i sigkill) odejde, systém pošle signál dítěti.

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

Váš problém je s použitím subprocess.check_output - máte pravdu, pomocí tohoto rozhraní nemůžete získat podřízené PID. Místo toho použijte 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

Abyste měli jistotu, že zabijete dítě při odchodu:

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. Jak nechat podřízený proces zemřít po odchodu rodiče?

  2. Je možné změnit prostředí nadřazeného procesu v Pythonu?

  3. Jak získat ID procesu pro ukončení procesu nohup?

  1. Nový rodičovský proces, když rodičovský proces zemře?

  2. Jak získat PID podle názvu procesu?

  3. Jak zabít <zaniklý> proces s rodičem 1

  1. Jak zabít proces, jehož rodič je init?

  2. Jak se Kali vypořádá s nadcházejícím Python 2 End-of-Life

  3. Jak nastavím pracovní adresář nadřazeného procesu?