2016-01-02 9 views
5

Ich möchte einen Prozess in einem Thread (der über eine große Datenbanktabelle iteriert) ausführen. Während der Thread läuft, möchte ich nur, dass das Programm wartet. Wenn dieser Thread länger als 30 Sekunden dauert, möchte ich den Thread beenden und etwas anderes tun. Indem ich den Thread töte, meine ich, dass ich möchte, dass er seine Aktivitäten beendet und Ressourcen freigibt.Die meisten Pythonic Weg, um einen Thread nach einer gewissen Zeit zu töten

Ich dachte, den besten Weg, dies durch ein Thread() ‚s join(delay) und is_alive() Funktionen zu tun war, und ein Event. Mit dem join(delay) kann ich mein Programm 30 Sekunden warten, bis der Thread fertig ist, und mit der is_alive() Funktion kann ich feststellen, ob der Thread seine Arbeit beendet hat. Wenn es seine Arbeit nicht beendet hat, wird das Ereignis festgelegt, und der Thread kann zu diesem Zeitpunkt nicht mehr funktionieren.

Ist diese Herangehensweise gültig, und ist dies der pythischste Weg, meine Problemaussage zu beantworten? Hier

ist ein Beispielcode:

import threading 
import time 

# The worker loops for about 1 minute adding numbers to a set 
# unless the event is set, at which point it breaks the loop and terminates 
def worker(e): 
    data = set() 
    for i in range(60): 
     data.add(i) 
     if not e.isSet(): 
      print "foo" 
      time.sleep(1) 
     else: 
      print "bar" 
      break 

e = threading.Event() 
t = threading.Thread(target=worker, args=(e,)) 
t.start() 

# wait 30 seconds for the thread to finish its work 
t.join(30) 
if t.is_alive(): 
    print "thread is not done, setting event to kill thread." 
    e.set() 
else: 
    print "thread has already finished." 

Antwort

2

ein Ereignis in diesem Fall zu verwenden ist funktioniert gut als Signalmechanismus und ist eigentlich in den threading module docs empfohlen.

Wenn Sie Ihre Fäden anmutig zu stoppen, machen sie nicht dämonisch und verwenden Sie einen geeigneten Signalmechanismus, wie ein Event.

Bei der Überprüfung der Thread-Terminierung verursachen Timeouts fast immer einen Platz für Fehler. Daher, während .join() mit einer Zeitüberschreitung für die erste Entscheidung, das Ereignis auszulösen ist in Ordnung, sollte die endgültige Überprüfung mit einem .join() ohne Zeitüberschreitung erfolgen.

# wait 30 seconds for the thread to finish its work 
t.join(30) 
if t.is_alive(): 
    print "thread is not done, setting event to kill thread." 
    e.set() 
    # The thread can still be running at this point. For example, if the 
    # thread's call to isSet() returns right before this call to set(), then 
    # the thread will still perform the full 1 second sleep and the rest of 
    # the loop before finally stopping. 
else: 
    print "thread has already finished." 

# Thread can still be alive at this point. Do another join without a timeout 
# to verify thread shutdown. 
t.join() 

Dies kann so etwas vereinfacht werden:

# Wait for at most 30 seconds for the thread to complete. 
t.join(30) 

# Always signal the event. Whether the thread has already finished or not, 
# the result will be the same. 
e.set() 

# Now join without a timeout knowing that the thread is either already 
# finished or will finish "soon." 
t.join() 
Verwandte Themen