Maison > Article > développement back-end > Comment terminer un thread en python
Comment terminer un thread en python : 1. Appelez la fonction stop et utilisez la fonction join pour attendre que le thread se termine correctement ; 2. Générez une exception dans le thread python ; 3. Utilisez "thread. rejoindre" pour terminer le fil de discussion.
L'environnement d'exploitation de cet article : système Windows 7, python version 3.5, ordinateur DELL G3.
Nous savons que pour terminer un thread en python, la méthode conventionnelle consiste à set/check--->flag ou lock de.
Cette méthode est-elle bonne ?
Probablement pas bon ! Parce que dans tous les langages de programmation, terminer un thread soudainement n'est de toute façon pas un bon modèle de conception .
En même temps
Certains cas sont encore pires, comme par exemple :
Pour faire simple, un grand groupe de nos threads partage des ressources communes. Vous souhaitez que l'un des threads "quitte" Si ce fil occupe des ressources, alors il sera obligé de quitter. C'est juste que les ressources sont bloquées et personne ne peut les obtenir ! N'est-ce pas un peu similaire à l'intrigue d'un roman sur la culture des immortels ?
Savez-vous pourquoi le threading n'a qu'un début mais pas de fin ?
Vous voyez, les threads sont généralement utilisés pour les connexions réseau, la libération des ressources système et le vidage des fichiers de streaming. Ceux-ci sont tous liés aux IO. Si vous fermez soudainement le thread, que devez-vous faire si ces <.> ne sont pas bien fermés ? Êtes-vous simplement en train de créer des bugs pour vous-même ? ah ? !
Donc, la chose la plus importante dans ce genre de chose n'est pas de mettre fin au fil de discussion mais deSolution · 壹Une façon plus agréable est d'avoir un indicateur de demande de sortie avec chaque thread, et de le vérifier à un certain intervalle dans le fil pour voir si c'est le bon moment . Laissé seul !nettoyer le fil.
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()Comme indiqué dans cette partie du code, vous devez explicitement appeler la fonction stop() lorsque vous souhaitez quitter le thread, et utiliser la fonction join() pour attendre que le thread
quitte de manière appropriée. Les threads doivent vérifier périodiquement l’indicateur d’arrêt.
Cependant, il existe certains scénarios d'utilisation dans lesquels vous avez vraiment besoin de tuer un thread : par exemple, lorsque vous encapsulez une bibliothèque externe, mais que la bibliothèque externeappelle pendant une longue période, vous Vous voulez interrompre ce processus.
[Recommandé :Tutoriel vidéo Python]
Solution · 20La solution suivante est d'autoriser la levée d'une exception dans le thread Python (bien sûr Il y a certaines restrictions).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 )Comme décrit dans les commentaires, ce n'est pas une "panacée", car si le thread est occupé en dehors de l'interpréteur python, alors l'exception du terminal ne sera pas interceptée~Ce code Le Une manière raisonnable de l'utiliser est de laisser le thread intercepter une
exception spécifique, puis d'effectuer l'opération de nettoyage. De cette façon, vous pouvez terminer une tâche et la nettoyer de manière appropriée.
Solution · 3Si nous voulons faire quelque chose de similaire à la méthode d'interruption, nous pouvons utiliser la méthode thread.join.join的原理就是依次检验线程池中的线程是否结束,没有结束就阻塞直到线程结束,如果结束则跳转执行下一个线程的join函数。 先看看这个: 1. 阻塞主进程,专注于执行多线程中的程序。 2. 多线程多join的情况下,依次执行各线程的join方法,前头一个结束了才能执行后面一个。 3. 无参数,则等待到该线程结束,才开始执行下一个线程的join。 4. 参数timeout为线程的阻塞时间,如 timeout=2 就是罩着这个线程2s 以后,就不管他了,继续执行下面的代码。rrree
La méthode de jointure par défaut est sans paramètres et mode de blocage. Seul le thread enfant s'exécutera avant d'en exécuter d'autres.
1. Deux threads sont démarrés en même temps et la fonction de jointure est exécutée. 2. Après que le thread wait1 s'exécute (attende) pendant 3 secondes, il se termine. 3. Après que le thread wait2 s'exécute (attende) pendant 8 secondes, l'opération se termine. 4. L'exécution de la fonction de jointure (retournée au processus principal) se termine.Le paramètre de join, c'est-à-dire le paramètre de timeout, est changé en 2, c'est-à-dire join (2), alors le résultat est le suivant :Il s'agit de la méthode de jointure par défaut, qui consiste à rejoindre une fois que le thread a commencé à s'exécuter. Faites attention à cela. Après avoir rejoint, le thread principal doit attendre que le thread enfant se termine avant. retour. ligne principale.
join(2) est : je vous donnerai deux secondes pour le sous-thread, et je partirai après chaque 2 secondes, je n'en aurai pas. aucun souci !
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!