400 Stimmen

Wie startet man einen Hintergrundprozess in Python?

Ich versuche, ein Shell-Skript auf die viel besser lesbare Python-Version zu portieren. Das ursprüngliche Shell-Skript startet mehrere Prozesse (Dienstprogramme, Monitore, etc.) im Hintergrund mit "&". Wie kann ich den gleichen Effekt in Python erreichen? Ich möchte, dass diese Prozesse nicht absterben, wenn die Python-Skripte beendet sind. Ich bin mir sicher, dass es irgendwie mit dem Konzept eines Daemons zusammenhängt, aber ich konnte nicht herausfinden, wie man das einfach machen kann.

508voto

Dan Punkte 11425

Während jkp Lösung funktioniert, ist die neuere Methode (und die in der Dokumentation empfohlene) die Verwendung der subprocess Modul. Für einfache Befehle ist es gleichwertig, aber es bietet mehr Optionen, wenn Sie etwas Kompliziertes machen wollen.

Beispiel für Ihren Fall:

import subprocess
subprocess.Popen(["rm","-r","some.file"])

Dies wird ausgeführt rm -r some.file im Hintergrund. Beachten Sie, dass der Aufruf von .communicate() auf das Objekt, das von Popen wird blockiert, bis es fertig ist, also tun Sie das nicht, wenn Sie wollen, dass es im Hintergrund läuft:

import subprocess
ls_output=subprocess.Popen(["sleep", "30"])
ls_output.communicate()  # Will block for 30 seconds

Siehe die Dokumentation aquí .

Außerdem möchte ich eine Klarstellung vornehmen: Der Begriff "Hintergrund", wie Sie ihn hier verwenden, ist ein reines Shell-Konzept; technisch gesehen meinen Sie damit, dass Sie einen Prozess starten wollen, ohne ihn zu blockieren, während Sie auf seine Fertigstellung warten. Allerdings habe ich "Hintergrund" hier verwendet, um Shell-Hintergrund-ähnliches Verhalten zu beziehen.

106voto

jkp Punkte 74580

備考 : Diese Antwort ist nicht mehr so aktuell wie bei ihrer Veröffentlichung im Jahr 2009. Unter Verwendung der subprocess Das in anderen Antworten gezeigte Modul wird nun empfohlen in den Unterlagen

(Beachten Sie, dass das Modul subprocess leistungsfähigere Möglichkeiten zum Erzeugen neuer Prozesse und zum Abrufen ihrer Ergebnisse bietet; die Verwendung dieses Moduls ist diesen Funktionen vorzuziehen).


Wenn Sie möchten, dass Ihr Prozess im Hintergrund startet, können Sie entweder system() und rufen es auf die gleiche Weise wie Ihr Shell-Skript auf, oder Sie können spawn es:

import os
os.spawnl(os.P_DETACH, 'some_long_running_command')

(alternativ können Sie auch das weniger portable os.P_NOWAIT Flagge).

Siehe die Dokumentation hier .

56voto

Eli Courtwright Punkte 174547

Sie wollen wahrscheinlich die Antwort auf "Wie man einen externen Befehl in Python aufruft" .

Der einfachste Ansatz ist die Verwendung der os.system Funktion, z.B.:

import os
os.system("some_command &")

Grundsätzlich gilt, dass alles, was Sie an die system Funktion wird genauso ausgeführt, wie wenn Sie sie in einem Skript an die Shell übergeben hätten.

40voto

Jimmy KD Punkte 543

Utilice subprocess.Popen() mit dem close_fds=True der es dem erzeugten Unterprozess ermöglicht, sich vom Python-Prozess selbst zu lösen und weiterzulaufen, auch wenn Python beendet wird.

https://gist.github.com/yinjimmy/d6ad0742d03d54518e9f

import os, time, sys, subprocess

if len(sys.argv) == 2:
    time.sleep(5)
    print 'track end'
    if sys.platform == 'darwin':
        subprocess.Popen(['say', 'hello'])
else:
    print 'main begin'
    subprocess.Popen(['python', os.path.realpath(__file__), '0'], close_fds=True)
    print 'main end'

39voto

f p Punkte 3105

Ich fand dies aquí :

Unter Windows (Win XP) wird der übergeordnete Prozess nicht beendet, bis die longtask.py hat seine Arbeit beendet. Das ist nicht das, was Sie in einem CGI-Skript wollen. Das Problem ist nicht spezifisch für Python, in der PHP-Gemeinschaft sind die Probleme die gleichen.

Die Lösung besteht darin, die DETACHED_PROCESS Flagge für Prozesserstellung zu den zugrunde liegenden CreateProcess Funktion in win API. Wenn Sie pywin32 installiert haben, können Sie das Flag aus dem win32process-Modul importieren, ansonsten sollten Sie es selbst definieren:

DETACHED_PROCESS = 0x00000008

pid = subprocess.Popen([sys.executable, "longtask.py"],
                       creationflags=DETACHED_PROCESS).pid

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X