Maison > développement back-end > Tutoriel Python > Comment terminer gracieusement les threads en Python et quand la résiliation forcée est-elle nécessaire ?

Comment terminer gracieusement les threads en Python et quand la résiliation forcée est-elle nécessaire ?

DDD
Libérer: 2024-12-28 15:34:19
original
643 Les gens l'ont consulté

How to Gracefully Terminate Threads in Python, and When is Forced Termination Necessary?

Résiliation gracieuse d'un fil de discussion

Terminer brusquement un fil de discussion est généralement déconseillé, en particulier en Python. Cela peut entraîner des fuites de ressources ou une corruption des données si des opérations critiques sont interrompues.

Approche recommandée

Une méthode privilégiée consiste à définir un indicateur ou un sémaphore pour indiquer que le thread devrait sortir. Le thread doit vérifier périodiquement cet indicateur et se terminer correctement s'il est défini.

Exemple :

import threading

class StoppableThread(threading.Thread):
    def __init__(self,  *args, **kwargs):
        super().__init__(*args, **kwargs)
        self._stop_event = threading.Event()

    def stop(self):
        self._stop_event.set()

    def stopped(self):
        return self._stop_event.is_set()
Copier après la connexion

Dans cet exemple, appelez stop() pour signaler au thread de quittez et utilisez join() pour attendre qu'il se termine correctement.

Forcé Résiliation

Dans des cas exceptionnels, vous devrez peut-être mettre fin de force à un fil de discussion. Cependant, cela doit être considéré comme un dernier recours.

Méthode de résiliation forcée :

import ctypes
import inspect

def _async_raise(tid, exctype):
    if not inspect.isclass(exctype):
        raise TypeError("Only types can be raised (not instances)")
    res = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), ctypes.py_object(exctype))
    if res == 0:
        raise ValueError("invalid thread id")
    elif res != 1:
        ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(tid), None)
        raise SystemError("PyThreadState_SetAsyncExc failed")

class ThreadWithExc(threading.Thread):
    def _get_my_tid(self):
        if not self.is_alive(): # Note: self.isAlive() on older version of Python
            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

        raise AssertionError("could not determine the thread's id")

    def raise_exc(self, exctype):
        _async_raise(self._get_my_tid(), exctype )
Copier après la connexion

Cette méthode s'appuie sur la fonction PyThreadState_SetAsyncExc pour déclencher une exception dans un domaine spécifique. fil de discussion. Cependant, il est important de noter que cette méthode n'est pas entièrement fiable et peut échouer si le thread est dans un appel système en dehors de l'interpréteur Python.

Précautions :

  • Évitez autant que possible d'utiliser cette méthode.
  • Si nécessaire, implémentez une logique de nettoyage spécifique au thread pour garantir que les données intégrité.
  • Utilisez cette méthode avec prudence, en comprenant les risques et les limites potentiels.

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!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal