2017-06-29 8 views
1

Ich habe einen einzigen Hintergrundprozess, der neben dem Hauptprozess läuft, wo er Queue verwendet, um zu kommunizieren (Multiprocessing, nicht Multithreading). Der Hauptprozess wird ständig ausgeführt, und der Hintergrundthread wird einmal pro Warteschlangenelement ausgeführt, sodass er bei einem Rückstand immer noch aufholen kann. Anstatt mit dem Hauptskript zu schließen (ich habe daemon dafür aktiviert), würde ich es lieber ausführen, bis die Warteschlange leer ist, dann speichern und beenden.Ermitteln, ob der Hauptprozess vom Hintergrundprozess beendet wurde

Es ist so begann:

q_send = Queue() 
q_recv = Queue() 
p1 = Process(target=background_process, args=(q_send, q_recv)) 
p1.daemon = True 
p1.start() 

Hier ist, wie der Hintergrundprozess läuft zur Zeit:

while True: 

    received_data = q_recv.get() 
    #do stuff 

Ein Weg, ich betrachtet habe, ist die Schleife wechseln die ganze Zeit zu laufen, aber Scheck die Größe der Warteschlange vor dem Versuch, es zu lesen, und warten Sie ein paar Sekunden, wenn es leer ist, bevor Sie es erneut versuchen. Es gibt jedoch ein paar Probleme. Der springende Punkt ist, dass es einmal pro Element ausgeführt wird. Wenn also 1000 eingereihte Befehle vorhanden sind, ist es ineffizient, die Warteschlangengröße vor jedem einzelnen zu überprüfen. Außerdem gibt es keine wirkliche Begrenzung für die Dauer des Hauptprozesses, ohne dass ein Update gesendet werden muss. Daher müsste ich das Timeout ziemlich hoch setzen, anstatt es sofort zu beenden, wenn die Verbindung unterbrochen wird und die Warteschlange geleert wird. Mit dem Hintergrund-Thread, der bis zu 2 GB RAM verwendet, könnte es wahrscheinlich so schnell wie möglich mit dem Beenden fertig werden.

Es wäre es auch viel mehr chaotisch aussehen:

afk_time = 0 
while True: 

    if afk_time > 300: 
     return 
    if not q_recv.qsize(): 
     time.sleep(2) 
     afk_time += 2 
    else: 
     received_data = q_recv.get() 
     #do stuff 

Ich kam in , und dachte, vielleicht den Hauptprozess immer von current_process() funktionieren kann, aber es gab einen Kommissionierung Fehler, wenn ich versuchte, Sende es an die Warteschlange.

Antwort

1

Queue.get hat ein Schlüsselwortargument timeout, das die Wartezeit auf ein Element bestimmt, wenn die Warteschlange leer ist. Wenn nach Ablauf des Zeitlimits kein Element verfügbar ist, wird eine Ausnahme Empty ausgelöst.

Entfernen und Zurückgeben eines Elements aus der Warteschlange. Wenn der optionale args-Block true ist und das Timeout None (der Standardwert) ist, blockieren Sie, falls erforderlich, bis ein Element verfügbar ist. Wenn das Zeitlimit eine positive Zahl ist, blockiert es höchstens Timeout-Sekunden und löst die Empty-Ausnahme aus, wenn innerhalb dieser Zeit kein Element verfügbar war. Andernfalls (Block ist false), gebe ein Element zurück, wenn eines sofort verfügbar ist, sonst erhöhe die Empty-Ausnahme (Timeout wird in diesem Fall ignoriert).

So können Sie diesen Fehler ausnehmen und brechen aus der Schleife:

try: 
    received_data = q_recv.get(timeout=300) 
except queue.Empty: 
    return 
+0

Danke, wenn es keine bessere Lösungen ist werde ich wohl das tun, wird immer noch nicht um das zweite Problem, das ich erwähnt Aber jetzt werde ich testen müssen, wie oft Dinge gesendet werden, um das Timeout so niedrig wie möglich zu bekommen :) – Peter

+0

@Peter Können Sie Ihr genaues Ziel noch einmal aufzeigen? Ich habe das Gefühl, etwas verpasst zu haben (besonders bei diesem zweiten Problem). Und warum willst du den Hintergrundprozess überhaupt verlassen? Was passiert, wenn der Hauptprozess später etwas an die Warteschlange sendet? –

+0

Ich möchte nur, dass es beendet wird, nachdem der Hauptprozess beendet wurde, da das bedeutet, dass keine Warteschlangenelemente mehr hinzugefügt werden. Alles, was ich tun muss, ist die Verarbeitung der Warteschlange zu beenden, so dass die Zeitüberschreitung als Workaround dient, aber im besten Fall würde es sofort wissen, dass der Hauptprozess beendet ist und keine Zeitüberschreitung benötigt. – Peter

Verwandte Themen