So beenden Sie einen Thread in Python: 1. Rufen Sie die Stop-Funktion auf und warten Sie mit der Join-Funktion, bis der Thread ordnungsgemäß beendet wird. 2. Lösen Sie eine Ausnahme im Python-Thread aus. 3. Verwenden Sie „thread.join“, um zu beenden der Thread.
Die Betriebsumgebung dieses Artikels: Windows 7-System, Python-Version 3.5, DELL G3-Computer.
Wir wissen, dass zum Beenden eines Threads in Python die herkömmliche Methode darin besteht, Setzen/Überprüfen --->Markieren oder Sperren.
Ist diese Methode gut?
Es sollte nicht gut sein! Denn in allen Programmiersprachen ist das plötzliche Beenden eines Threads sowieso kein gutes Entwurfsmuster.
GleichzeitigIn einigen Fällen ist es sogar noch schlimmer, wie zum Beispiel:
Wenn ein Thread eine kritische Ressource öffnet, die vernünftigerweise geschlossen werden muss, wie zum Beispiel das Öffnen einer lesbaren und beschreibbaren DateiWissen Sie, warum das Einfädeln nur einen Anfang, aber kein Ende hat?den Thread aufzuräumenThreads werden im Allgemeinen für Netzwerkverbindungen, die Freigabe von Systemressourcen und das Speichern von Streaming-Dateien verwendet. Was sollten Sie tun, wenn Sie den Thread plötzlich schließen? Erzeugst du nur Fehler für dich selbst? Ah? !
Das Wichtigste bei so etwas ist also nicht, den Thread zu beenden, sondern
.Eine schönere Möglichkeit besteht darin, jeden Thread mit einem Exit-Request-Flag zu versehen und es in einem bestimmten Intervall im Thread zu überprüfen, um zu sehen, ob es Zeit ist, den Thread zu verlassen!Lösung · 1
import threading class StoppableThread(threading.Thread): """Thread class with a stop() method. The thread itself has to check regularly for the stopped() condition.""" def __init__(self): super(StoppableThread, self).__init__() self._stop_event = threading.Event() def stop(self): self._stop_event.set() def stopped(self): return self._stop_event.is_set()
entsprechend beendet wird
. Threads sollten das Stopp-Flag regelmäßig überprüfen.Es gibt jedoch einige Nutzungsszenarien, in denen Sie einen Thread wirklich beenden müssen: zum Beispiel, wenn Sie eine externe Bibliothek kapseln, die externe Bibliothek jedoch schon seit längerem aufruft
, sodass Sie den Prozess unterbrechen möchten.[Empfohlen: Python-Video-Tutorial
]Die nächste Lösung besteht darin, das Auslösen einer Ausnahme im Python-Thread zuzulassen (natürlich gibt es einige Einschränkungen).def _async_raise(tid, exctype): '''Raises an exception in the threads with id tid''' if not inspect.isclass(exctype): raise TypeError("Only types can be raised (not instances)") res = ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, ctypes.py_object(exctype)) if res == 0: raise ValueError("invalid thread id") elif res != 1: # "if it returns a number greater than one, you're in trouble, # and you should call it again with exc=NULL to revert the effect" ctypes.pythonapi.PyThreadState_SetAsyncExc(tid, 0) raise SystemError("PyThreadState_SetAsyncExc failed") class ThreadWithExc(threading.Thread): '''A thread class that supports raising exception in the thread from another thread. ''' def _get_my_tid(self): """determines this (self's) thread id CAREFUL : this function is executed in the context of the caller thread, to get the identity of the thread represented by this instance. """ if not self.isAlive(): raise threading.ThreadError("the thread is not active") # do we have it cached? if hasattr(self, "_thread_id"): return self._thread_id # no, look for it in the _active dict for tid, tobj in threading._active.items(): if tobj is self: self._thread_id = tid return tid # TODO: in python 2.6, there's a simpler way to do : self.ident raise AssertionError("could not determine the thread's id") def raiseExc(self, exctype): """Raises the given exception type in the context of this thread. If the thread is busy in a system call (time.sleep(), socket.accept(), ...), the exception is simply ignored. If you are sure that your exception should terminate the thread, one way to ensure that it works is: t = ThreadWithExc( ... ) ... t.raiseExc( SomeException ) while t.isAlive(): time.sleep( 0.1 ) t.raiseExc( SomeException ) If the exception is to be caught by the thread, you need a way to check that your thread has caught it. CAREFUL : this function is executed in the context of the caller thread, to raise an excpetion in the context of the thread represented by this instance. """ _async_raise( self._get_my_tid(), exctype )
spezifische Ausnahme
ab und führen Sie Bereinigungsvorgänge durch. Auf diese Weise können Sie eine Aufgabe beenden und entsprechend bereinigen.Lösung · 3
Wenn wir etwas Ähnliches wie die Interrupt-Methode tun möchten, können wir die Methode thread.join verwenden.join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。 先看看这个: 1. 阻塞主进程,专注于执行多线程中的程序。 2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。 3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。 4. 参数timeout为线程的阻塞时间,如 timeout=2 就是罩着这个线程2s 以后,就不管他了,继续执行下面的代码。
# coding: utf-8 # 多线程join import threading, time def doWaiting1(): print 'start waiting1: ' + time.strftime('%H:%M:%S') + "\n" time.sleep(3) print 'stop waiting1: ' + time.strftime('%H:%M:%S') + "\n" def doWaiting2(): print 'start waiting2: ' + time.strftime('%H:%M:%S') + "\n" time.sleep(8) print 'stop waiting2: ', time.strftime('%H:%M:%S') + "\n" tsk = [] thread1 = threading.Thread(target = doWaiting1) thread1.start() tsk.append(thread1) thread2 = threading.Thread(target = doWaiting2) thread2.start() tsk.append(thread2) print 'start join: ' + time.strftime('%H:%M:%S') + "\n" for tt in tsk: tt.join() print 'end join: ' + time.strftime('%H:%M:%S') + "\n"
Die Standard-Join-Methode ist keine Parameter, Blockierungsmodus, nur der untergeordnete Thread wird ausgeführt, bevor andere ausgeführt werden.
1. Zwei Threads werden gleichzeitig gestartet und die Join-Funktion ausgeführt.
2. Nachdem der Warte1-Thread 3 Sekunden lang ausgeführt (wartet) wurde, endet er. 3. Nachdem der Warte2-Thread 8 Sekunden lang ausgeführt (wartet) wurde, endet der Vorgang. 4. Die Join-Funktion (zurück zum Hauptprozess) wird beendet. Dies ist die Standard-Join-Methode. Beachten Sie Folgendes: Nach dem Beitritt muss der Haupt-Thread warten, bis der Unter-Thread beendet ist, bevor er zum Haupt-Thread zurückkehrt.wating1-Thread nach drei Sekunden Ausführung (Warten) abgeschlossen.Join-Parameter, bei dem es sich um den Timeout-Parameter handelt, wird auf 2 geändert, d wird ausgeführt.
Das obige ist der detaillierte Inhalt vonSo beenden Sie einen Thread in Python. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!