Table des matières
Avant-propos · Zéro
Maison développement back-end Tutoriel Python Comment terminer un thread en python

Comment terminer un thread en python

Mar 02, 2021 pm 02:02 PM
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.

Comment terminer un thread en python

L'environnement d'exploitation de cet article : système Windows 7, python version 3.5, ordinateur DELL G3.

Avant-propos · Zéro

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 :

  • Quand un fil de discussion ouvre une ressource critique qui doit être fermé raisonnablement, comme ouvrir un fichier lisible et inscriptible ;
  • Le fil a créé plusieurs autres fils de discussion, et ces fils de discussion doivent également être fermés (il y a un risque d'errance des fils de discussion !).

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 de

nettoyer le fil.

Solution · 壹

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 !

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()
Copier après la connexion
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 externe

appelle pendant une longue période, vous Vous voulez interrompre ce processus.

[Recommandé :

Tutoriel vidéo Python]

Solution · 20

La 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 )
Copier après la connexion
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 · 3

Si 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 以后,就不管他了,继续执行下面的代码。
Copier après la connexion
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.

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.

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 :

  1. Deux Deux threads sont démarrés en même temps et la fonction de jointure est exécutée.

  2. Le thread de surveillance 1 s'est terminé après avoir exécuté (attendu) pendant trois secondes.

  3. rejoindre la sortie (deux 2, un total de 4, 36-32=4, correct).

  4. Le thread wait2 ne s'est pas terminé dans le temps d'attente (4 s) spécifié par join, il a donc terminé son exécution plus tard.

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!

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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Comment réparer l'audio si vous n'entendez personne
4 Il y a quelques semaines By 尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Comment déverrouiller tout dans Myrise
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Le plan Python de 2 heures: une approche réaliste Le plan Python de 2 heures: une approche réaliste Apr 11, 2025 am 12:04 AM

Vous pouvez apprendre les concepts de programmation de base et les compétences de Python dans les 2 heures. 1. Apprenez les variables et les types de données, 2. Flux de contrôle maître (instructions et boucles conditionnelles), 3. Comprenez la définition et l'utilisation des fonctions, 4. Démarrez rapidement avec la programmation Python via des exemples simples et des extraits de code.

Comment lire la file d'attente redis Comment lire la file d'attente redis Apr 10, 2025 pm 10:12 PM

Pour lire une file d'attente à partir de Redis, vous devez obtenir le nom de la file d'attente, lire les éléments à l'aide de la commande LPOP et traiter la file d'attente vide. Les étapes spécifiques sont les suivantes: Obtenez le nom de la file d'attente: Nommez-le avec le préfixe de "Fitre:" tel que "Fitre: My-Quyue". Utilisez la commande LPOP: éjectez l'élément de la tête de la file d'attente et renvoyez sa valeur, telle que la file d'attente LPOP: My-Queue. Traitement des files d'attente vides: si la file d'attente est vide, LPOP renvoie NIL et vous pouvez vérifier si la file d'attente existe avant de lire l'élément.

Comment afficher la version serveur de redis Comment afficher la version serveur de redis Apr 10, 2025 pm 01:27 PM

Question: Comment afficher la version Redis Server? Utilisez l'outil de ligne de commande redis-Cli --version pour afficher la version du serveur connecté. Utilisez la commande Info Server pour afficher la version interne du serveur et devez analyser et retourner des informations. Dans un environnement de cluster, vérifiez la cohérence de la version de chaque nœud et peut être vérifiée automatiquement à l'aide de scripts. Utilisez des scripts pour automatiser les versions de visualisation, telles que la connexion avec les scripts Python et les informations d'impression.

Comment démarrer le serveur avec redis Comment démarrer le serveur avec redis Apr 10, 2025 pm 08:12 PM

Les étapes pour démarrer un serveur Redis incluent: Installez Redis en fonction du système d'exploitation. Démarrez le service Redis via Redis-Server (Linux / MacOS) ou Redis-Server.exe (Windows). Utilisez la commande redis-Cli Ping (Linux / MacOS) ou redis-Cli.exe Ping (Windows) pour vérifier l'état du service. Utilisez un client redis, tel que redis-cli, python ou node.js pour accéder au serveur.

Comment définir la taille de la mémoire Redis en fonction des besoins de l'entreprise? Comment définir la taille de la mémoire Redis en fonction des besoins de l'entreprise? Apr 10, 2025 pm 02:18 PM

Le réglage de la taille de la mémoire redis doit prendre en compte les facteurs suivants: volume de données et tendance de croissance: estimer la taille et le taux de croissance des données stockées. Type de données: différents types (tels que les listes, les hachages) occupent une mémoire différente. Politique de mise en cache: le cache complet, le cache partiel et les politiques de phasage affectent l'utilisation de la mémoire. Péx commercial: laissez suffisamment de mémoire pour faire face aux pics de trafic.

Quels sont les paramètres de configuration de la mémoire redis? Quels sont les paramètres de configuration de la mémoire redis? Apr 10, 2025 pm 02:03 PM

** Le paramètre central de la configuration de la mémoire redis est MaxMemory, qui limite la quantité de mémoire que Redis peut utiliser. Lorsque cette limite est dépassée, Redis exécute une stratégie d'élimination selon maxmemory-policy, notamment: Noeviction (rejeter directement l'écriture), AllKeys-LRU / Volatile-LRU (éliminé par LRU), AllKeys-Random / Volatile-Random (éliminé par élimination aléatoire) et TTL volatile (temps d'expiration). D'autres paramètres connexes incluent des échantillons maxmemory (quantité d'échantillon LRU), compression RDB

Quel est l'impact de la persistance redis sur la mémoire? Quel est l'impact de la persistance redis sur la mémoire? Apr 10, 2025 pm 02:15 PM

Redis Persistance prendra une mémoire supplémentaire, RDB augmente temporairement l'utilisation de la mémoire lors de la génération d'instantanés, et AOF continue de prendre de la mémoire lors de l'ajout de journaux. Les facteurs d'influence comprennent le volume des données, la politique de persistance et la configuration de Redis. Pour atténuer l'impact, vous pouvez raisonnablement configurer les stratégies d'instantané RDB, optimiser la configuration AOF, mettre à niveau le matériel et le surveiller l'utilisation de la mémoire. En outre, il est crucial de trouver un équilibre entre les performances et la sécurité des données.

Python vs C: applications et cas d'utilisation comparés Python vs C: applications et cas d'utilisation comparés Apr 12, 2025 am 12:01 AM

Python convient à la science des données, au développement Web et aux tâches d'automatisation, tandis que C convient à la programmation système, au développement de jeux et aux systèmes intégrés. Python est connu pour sa simplicité et son écosystème puissant, tandis que C est connu pour ses capacités de contrôle élevées et sous-jacentes.

See all articles