Ich habe einen Threaded Python-Daemon. Wie jeder gute Daemon möchte er alle seine Worker-Threads starten und dann warten, bis es beendet wird. Das normale Signal für die Beendigung ist SIGTERM
, und in den meisten Sprachen würde ich warten, um auf ein Ereignis oder einen Mutex zu warten, so dass threading.Event
Sinn für mich machte. Das Problem ist, dass Pythons Event
Objekt und Unix-Signale nicht gut zusammen zu spielen scheinen.Warum führt die Verwendung von threading.Event dazu, dass SIGTERM nicht abgefangen wird?
Dies funktioniert wie erwartet, endet am SIGTERM
:
import signal
import time
RUN = True
def handle(a, b):
global RUN
print "handled"
RUN = False
signal.signal(signal.SIGTERM, handle)
while RUN:
time.sleep(0.250)
print "Stopping"
aber dies führt zu keiner SIGTERM
geliefert wird (dh ganz abgesehen von Aufhören, "behandelt" wird nie gedruckt):
import signal
import threading
RUN_EVENT = threading.Event()
def handle(a, b):
print "handled"
RUN_EVENT.set()
signal.signal(signal.SIGTERM, handle)
RUN_EVENT.wait()
print "Stopping"
Also meine Frage ist:
- Bin ich missbrauchen
threading.Event
in irgendeiner Weise? - Wenn nicht, gibt es eine andere Alternative als den Poll-and-Sleep-Mechanismus aus dem ersten Beispiel?
- Auch wenn ich nicht bin, warum benutzt
threading.Event
den Signalhandler?
Lästiges Feature von Python, aber perfekte Lösung. Vielen Dank. Ich gestehe, dass es mir nicht in den Sinn gekommen ist, nach zusätzlichen Beschränkungen für den Signalgebrauch zu suchen, da ich wusste, dass das äquivalente C gut funktionieren würde. –
Bedeutet dies, dass die einzige Möglichkeit, Signale zu verarbeiten, darin besteht, den Hauptthread (Eltern) den Signalen zuzuordnen (durch Blockieren von 'signal.pause()')? Was das bedeutet, ist, dass der Hauptthread nichts mehr tun kann. Mit anderen Worten, Sie können kein Master-/Worker-Modell haben (wo die 2 Threads miteinander kommunizieren), aber Sie benötigen ein Master/Worker + Worker-Modell (wo die 2 Arbeiter miteinander reden und der Master nichts tut). –