2016-10-03 1 views
0

Ich habe einen Django-basierten Server und rufe ein Skript an, das eine ganze Menge Arbeit leistet. Das muss asynchron sein, also benutze ich Popen. Zum Debuggen möchte ich jedoch stdout und stderr von PIPE in eine Datei umleiten. Beeinflusst dies die asynchrone Leistung?Kann ich eine Datei an Popen übergeben und sie trotzdem asynchron ausführen lassen?

Wie soll ich sicherstellen, dass die Datei richtig öffnet und schließt, wenn das Python-Skript selbst bereits geschehen ist (und hat einen Rückruf. Gemacht)

Antwort

1

Popen läuft asynchron standardmäßig. Das Objekt Popen kann später gespeichert und abgefragt werden.

p = subproccess.Popen(executable) 

# continue with other work 

p.poll() # returns None if p is still running, returncode otherwise 
p.terminate() # closes the process forcefully 

p.wait() # freezes the execution until process finishes - makes it synchronous 

alles, was benötigt wird, ist p irgendwo zu speichern, bis ihr Status überprüft werden muss, z.B. in einer globalen Liste gestarteter Prozesse, wenn es keinen besseren Ort gibt.

UPDATE

Das Problem scheint zu sein, wie eine Datei zu öffnen, geben Sie es an Popen und schließen Sie die Datei, wenn der Prozess abgeschlossen ist, ohne irgendwelche Referenzen zu halten.

def run_process(executable, filename): 
    with open(filename, 'w') as f: 
     subprocess.Popen(executable, stdout=f).wait() 

Thread(target=run_process, args=(executable, filename)).start() 

Run es und vergessen Sie es:

Dies kann einfach mit einem Gewinde erfolgen. run_process wird eingefroren, bis der Prozess beendet ist und dann wird die Datei geschlossen, aber das alles passiert in einem anderen Thread.

Hinweis: Sie möglicherweise oder nicht egal, was mit dem Thread oder dem Prozess passiert, wenn sie nicht fertig sind, wenn der Django-Prozess abgeschlossen ist.

Um dies zu handhaben, könnten Sie einen komplexeren Thread erstellen, an den Sie sich erinnern würden, und ihn vor dem Beenden von django stoppen. es kann auch den Prozess schließen oder darauf warten, dass es beendet wird ...

+0

Ich weiß es läuft Asynchron standardmäßig bedeuten, dass ich, wenn ich es tue stdout = f wobei f ein Python-Datei-Objekt, was passiert, wenn Python die Datei des Referenzrahmen verläßt, während die subprocess noch läuft? –

+0

@DylanLawrence Ach das! Die Datei bleibt geöffnet, bis Sie sie schließen (verwenden Sie nicht 'mit offenen (...)' obwohl). Auf der anderen Seite sollten Sie den Dateiverweis etwas behalten, damit Sie ihn später schließen können. – zvone

+0

Also das einzige Problem damit ist, ist dies eine Web-orientierte Anwendung, so dass dieses Skript Clients behandelt und der Subprozess Aufruf ist im Grunde "Feuer und vergessen." Wenn ich die Variable nicht behalte, kümmert sich das Betriebssystem um die Bereinigung? –

1

Es hängt davon ab, wie asynchron Ihr Programm sein muss. Schreibt auf den Standard-Dateicache des Betriebssystems, der normalerweise schnell ist, aber von Zeit zu Zeit warten kann, wenn Daten auf den Datenträger geschrieben werden. Normalerweise ist das kein Problem.

Da es sich bei stdout nicht um eine Konsole handelt, werden gepufferte Schreibvorgänge ausgeführt. Dies kann ein Problem sein, wenn das Programm auf einen nicht standardmäßigen Fehler stößt, bei dem die Pipe nicht gelöscht wird. Die Pufferung kann auch verzögern, was sich in der Datei befindet, so dass zum Beispiel ein externes Programm, das die Datei kattiert, die Protokolle möglicherweise nicht sofort sieht.

Der übergeordnete Prozess sollte die Ansicht der Datei nach dem Start des untergeordneten Elements schließen, und das Betriebssystem sorgt dafür, dass die Datei beim Beenden des Prozesses geschlossen wird.

with open('stdout', 'w') as out, open('stderr', 'w') as err: 
    proc = subprocess.Popen(['myprog'], stdout=out, stderr=err) 
+0

Ok, also wird die Verwendung von 'with' die Ausführung des Python-Skripts überhaupt nicht halten? –

+0

Das übergeordnete Skript? Nein, es läuft mit voller Geschwindigkeit. Sie haben das Dateihandle an das untergeordnete Element übergeben, als es gestartet wurde, und das übergeordnete Element ist jetzt vollständig aus der Schleife entfernt. Das Kind schreibt direkt in den Dateicache des Betriebssystems. – tdelaney

+0

@tdelaney Sollte die 'file.close()', die am Ende des 'with' Blocks aufgerufen wird, nicht die Datei beeinflussen? – zvone

Verwandte Themen