GNU/Linux >> LINUX-Kenntnisse >  >> Linux

Wie kann man einen mit subprocess.check_output() erstellten Python-Kindprozess beenden, wenn der Elternteil stirbt?

Ja, Sie können dies auf zwei Arten erreichen. Beide erfordern die Verwendung von Popen statt check_output . Die erste ist eine einfachere Methode, die try..finally wie folgt verwendet:

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

Dies fängt sigint (Tastatur-Interrupt) und sigterm ab, aber nicht sigkill (wenn Sie Ihr Skript mit -9 beenden).

Die andere Methode ist etwas komplexer und verwendet prctl PR_SET_PDEATHSIG von ctypes. Das System sendet ein Signal an das Kind, sobald der Elternteil aus irgendeinem Grund (sogar Sigkill) verlässt.

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

Ihr Problem liegt in der Verwendung von subprocess.check_output - Sie haben Recht, Sie können die untergeordnete PID nicht über diese Schnittstelle abrufen. Verwenden Sie stattdessen 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

Um sicherzustellen, dass Sie das Kind beim Beenden töten:

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. Neuer übergeordneter Prozess, wenn der übergeordnete Prozess stirbt?

  2. Warum ist die PGID der untergeordneten Prozesse nicht die PGID des übergeordneten Prozesses?

  3. Wie Kali mit dem bevorstehenden Python 2 End-of-Life umgeht

  4. Wie kann man einen untergeordneten Prozess sterben lassen, nachdem der übergeordnete Prozess beendet wurde?

  5. Ist es möglich, die Umgebung eines übergeordneten Prozesses in Python zu ändern?

So finden Sie die Prozess-ID eines Programms und beenden es [Kurztipp]

Wie beendet man einen Prozess, dessen Eltern Init ist?

So beenden oder beenden Sie einen Linux-Prozess:Der ultimative Leitfaden

Wie bekomme ich die Prozess-ID, um einen Nohup-Prozess zu beenden?

Wie bekomme ich PID nach Prozessname?

So beenden Sie einen <defunct>-Prozess mit übergeordnetem 1