2016-06-29 3 views
2

Ich habe ein Django-Projekt, in dem ein Benutzer mehrere Subprozesse gleichzeitig starten kann. Die Prozesse können einige Zeit dauern und somit kann der Benutzer mit anderen Aspekten der App weiterarbeiten. In jedem Fall kann der Benutzer alle laufenden Prozesse ansehen und einen von ihnen abfragen, um zu überprüfen, ob es vorbei ist. Dafür muss ich den Prozess mit seiner PID abfragen. Popen.poll() erwartet ein subprocess.Peopen-Objekt, während alles, was ich habe, die PID dieses Objekts ist. Wie kann ich das gewünschte Ergebnis erzielen?Abruf eines Subprozesses mit Hilfe von pid

in models.py:

class Runningprocess(models.Model): 
    #some other fields 
    p_id=models.CharField(max_length=500) 
    def __str__(self): 
     return self.field1 

In views.py:

def run_process(): 
    .... 
    p= subprocess.Popen(cmd, shell =True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) 
    new_p=Runningprocess() 
    new_p.p_id=p.pid 
    .... 
    new_p.save() 
    return HttpResponseRedirect('/home/') 

def check(request,pid): 
    #here i want to be able to poll the subprocess using the p_id e.g something like: 
    checkp = pid.poll() #this statement is wrong 
    if checkp is None: 
      do something 
    else: 
      do something else 

Ich brauche nur eine gültige Anweisung anstelle von 'checkp = pid.poll()'

+0

Können Sie ein [MCVE] (http://stackoverflow.com/help/mcve) anzeigen, um das Problem zu reproduzieren. – Cyrbil

+0

Sehen Sie die bearbeitete Frage –

+0

Nicht vorschlagen, das ist eine gute Idee in Ihrem speziellen Fall, aber um zu überprüfen, ob ein Prozess mit einer bestimmten PID ausgeführt wird, können Sie 'os.kill (pid, 0)' verwenden, was "OSError" if Kein Prozess mit dieser PID wird ausgeführt. – Aya

Antwort

1

Nicht mit PID abfragen

PID ist eine temporäre ID zugewiesen zu einem Prozess. Es bleibt solange in einem Prozess, wie der Prozess läuft. Wenn ein Prozess entweder beendet oder beendet wird, kann seine PID (oder nicht sofort) einem anderen Prozess zugewiesen werden. So kann eine PID eines Prozesses, die jetzt gültig ist, nach einiger Zeit nicht mehr gültig bleiben.

Jetzt, wie für einen Prozess abzufragen?

Dies ist, was ich in einem meiner Projekt tat:

psub = subprocess.Popen(something) 
# polling 

while psub.poll() is None: 
    pass 

aber der obige Code passen sie auf, könnte eine Sackgasse führen in. Um Deadlock zu vermeiden, können Sie zwei Ansätze verwenden:

  1. Zähler verwenden. Wenn der Zählerwert größer als ein fester Wert wird, beenden Sie den Prozess.

2. Timeout verwenden. Erhalten Sie die Startzeit, wenn der Prozess gestartet wurde und wenn der Prozess länger dauert als eine festgelegte Zeit - Kill.

start_time = time.time() 
timeout = 60 # 60 seconds 
while psub.poll() is None: 
    if time.time() - start_tym >= int(timeout): 
     psub.kill() 
+0

Das Problem besteht darin, dass der Benutzer von verschiedenen Stellen der Webapp aus mehrmals auf die View 'run_process()' zugreifen kann und dementsprechend verschiedene Prozesse gestartet werden. Bei einer bestimmten URL listet ich alle Prozesse auf, die derzeit im Runningprocesses-Modell gespeichert sind, und wenn ich auf eine dieser URLs klicke, wird der Benutzer zur Überprüfung weitergeleitet, wo ich prüfen muss, ob dieser bestimmte Prozess noch läuft oder nicht. Wenn es getan wird, möchte ich, dass bestimmte Dinge zusammen mit diesem Modell aus diesem Modell gelöscht werden. –

+1

@Code_aholic AFAIK, PID ist nicht zuverlässig. Was Sie für Ihren Fall tun können, ist. Lassen Sie den Controller von 'run_process()' in einem asynchronen Popen() - Prozess laufen. Speichern Sie die Prozess-PID in der DB und lassen Sie den gestarteten Prozess nun für jede Phase in die Datenbank schreiben, wie 'init', 'killed', 'complete'. Immer wenn der WebApp-Benutzer auf die PID-Showdaten von der DB klickt. –

+0

Naja, ich denke es lohnt sich einen Schuss zu geben. Ich hätte so darüber nachdenken sollen! Vielen Dank :). Obwohl ich ein Problem habe, kann der Prozess auch bis zu einigen Stunden dauern, also würde diese Methode in diesem Fall gut funktionieren? –