2017-09-12 2 views
2

Wir haben eine große Anwendung in Python geschrieben. Wir möchten Prozesse, die von unserer Anwendung gestartet wurden, sauber löschen, wenn wir sie schließen oder unterbrechen. Python-Code jedoch durch (z subprocess.Popen oder os.system), haben wir einen Befehl A, die startet einen weiteren subcommand B aber der Befehl B scheint mit dem Befehl keine Beziehung zu haben A. Der Vaterprozess des Befehls B ist der Initialisierungsprozess (mit PID 1). Wie wird der Prozess B in Python-Code (z. B. nach Strg + C) beendet?Wie werden alle von der Anwendung gestarteten Prozesse ordnungsgemäß beendet?

Zum Beispiel haben wir 2 Shell-Skripte und ein Python-Skript, das diese Shell-Skripte aufruft.

die erste Shell-Skript mycommand1.sh ist:

#!/bin/sh 
sleep 3600 & 

die zweite Shell-Skript mycommand2.sh ist:

#!/bin/sh 
sleep 3600 

das Python-Skript myscript.py ist:

import os 
import signal 
import subprocess 

def launchCommands(): 

    proc1 = subprocess.Popen('./mycommand1.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid) 
    print "the processus 1 has started" 

    proc2 = subprocess.Popen('./mycommand2.sh', stdout=subprocess.PIPE, shell = True, preexec_fn=os.setsid) 
    print "the processus 2 has started" 

    return proc1, proc2 


if __name__ == '__main__': 
    proc1 = None 
    proc2 = None 
    try: 
     proc1, proc2 = launchCommands() 
     while True: 
      pass 

    except KeyboardInterrupt: 
     print "Ctrl+C received! ..." 

     print "trying to kill the processus 2" 
     os.killpg(os.getpgid(proc2.pid), signal.SIGTERM) 
     print "processus 2 has been killed" 

     print "trying to kill the processus 1" 
     os.killpg(os.getpgid(proc1.pid), signal.SIGTERM) 
     print "processus 1 has been killed" 

Dann führen wir unser Python-Skript aus und unterbrechen es nach 3 Sekunden mit Strg + C. Hier ist der Ausgang nach der Unterbrechung.

$> python myscript.py 
the processus 1 has started 
the processus 2 has started 
^CCtrl+C received! ... 
trying to kill the processus 2 
processus 2 has been killed 
trying to kill the processus 1 
Traceback (most recent call last): 
File "myscript.py", line 33, in <module> 
    os.killpg(os.getpgid(proc1.pid), signal.SIGTERM) 
OSError: [Errno 3] No such process 

Wir zeigen alle „Schlaf“ Prozesse während und nach der Ausführung des Python-Skript (Natürlich gibt es keinen Schlaf-Prozess vor der Ausführung des Skripts Python ist).

Während des Laufens den myscript.py Befehl:

$> ps -ef | grep sleep 
    501 50700  1 0 2:21 ??   0:00.00 sleep 3600 
    501 50701 50699 0 2:21 ??   0:00.00 sleep 3600 
    501 50703 410 0 2:21 ttys002 0:00.00 grep sleep 

Nachdem Sie das Programm mit Strg + C unterbrechen:

$> ps -ef | grep sleep 
    501 50700  1 0 2:21 ??   0:00.00 sleep 3600 
    501 51025 410 0 2:23 ttys002 0:00.00 grep sleep 

Wie wir sehen können, wird der Prozess 1 wir versuchen, nicht zu töten, nicht vorhanden mehr und ein Prozess Schlaf, dessen Vater pid 1 immer existiert. Dieser Prozessschlaf kommt von der Ausführung des Skripts mycommand1.sh. Wie man diesen Prozessschlaf im Skript myscript.py richtig beendet (natürlich möchten wir nicht alle Schlafprozesse beenden)?

+0

ich es nicht wiedergeben kann. Ich habe alles gemacht, was Sie beschrieben – RedEyed

+0

Vielen Dank für Ihr Interesse an meinem Problem. Ich habe diese Experimente auf einem Mac gemacht (macOS Sierra 10.12.3) und meine Version von Python ist 2.7.13. Ich habe alle Codes kopiert, die ich in meine Frage geschrieben habe, ich habe gerade Rechte für die Shell-Skripte hinzugefügt, um den Python-Befehl zu starten (chmod 755 mycommand * .sh) und ich habe das Problem gut reproduziert. –

+0

Ich teste es auf Ubuntu 17 und kann es nicht reproduzieren. Ich habe es auch auf Python 2.7.13 getestet. – RedEyed

Antwort

0

Versuchen mycommand1.sh

#!/bin/sh 
foo(){ 
    cnt=0 
    while [ $cnt -le 100 ]; do 
     cnt=$((cnt+1)) 
     echo $0 $cnt 
     sleep 1 
    done 
} 

foo & 

und mycommand2.sh

#!/bin/sh 
foo(){ 
    cnt=0 
    while [ $cnt -le 100 ]; do 
     cnt=$((cnt+1)) 
     echo $0 $cnt 
     sleep 1 
    done 
} 

foo 

entfernen stdout=subprocess.PIPE von myscript.py Und überprüfen Sie es neu zu schreiben.

0

Ich befolge alle Ihre Anweisungen. Hier ist die Ausgabe:

$> python myscript.py 
    1427 
    the processus 1 has started 
    1428 
    the processus 2 has started 
    ./mycommand1.sh 1 
    ./mycommand2.sh 1 
    ./mycommand1.sh 2 
    ./mycommand2.sh 2 
    ^CCtrl+C received! ... 
    trying to kill the processus 2 
    processus 2 has been killed 
    trying to kill the processus 1 
    Traceback (most recent call last): 
    File "myscript.py", line 38, in <module> 
     os.killpg(os.getpgid(proc1.pid), signal.SIGTERM) 
    OSError: [Errno 3] No such process 
$> ./mycommand1.sh 3 
    ./mycommand1.sh 4 
    ./mycommand1.sh 5 
    ./mycommand1.sh 6 
    ./mycommand1.sh 7 
    ./mycommand1.sh 8 
    ./mycommand1.sh 9 

Nach Strg + C, das Skript mycommand1.sh läuft weiter.

Hinweis: 1427 und 1428 sind jeweils die pgid der Prozesse 1 und 2.

proc1or2 = subprocess.Popen('./mycommand1or2.sh', shell = True, preexec_fn=os.setsid) 
print(os.getpgid(proc1or2.pid)) 
print "the processus 1or2 has started" 
Verwandte Themen