Maison >développement back-end >Tutoriel Python >Comment intercepter l'exception d'un thread dans le thread appelant en Python ?

Comment intercepter l'exception d'un thread dans le thread appelant en Python ?

Susan Sarandon
Susan Sarandonoriginal
2024-11-09 09:25:02343parcourir

How to Catch a Thread's Exception in the Caller Thread in Python?

Détectez l'exception d'un thread dans le fil de l'appelant

La programmation multithread, les tâches exécutées simultanément, offre une efficacité dans la gestion des opérations complexes. Cependant, les exceptions rencontrées dans les threads peuvent devenir difficiles à gérer. En Python, le bloc standard « try-sauf » ne peut pas gérer les exceptions déclenchées dans un thread enfant. Cet article explore une technique permettant de capturer les exceptions d'un thread dans le thread appelant, permettant ainsi aux développeurs de les gérer efficacement.

Comprendre le problème

Considérez le scénario suivant : un script exécute un fichier copier dans un fil de discussion séparé, dans le but d'afficher des indicateurs de progression. Cependant, lorsque la copie d'un fichier échoue, une exception est levée dans le thread. L'extrait de code ci-dessous tente de gérer cette exception :

try:
    threadClass = TheThread(param1, param2, etc.)
    threadClass.start()   ##### **Exception takes place here**
except:
    print "Caught an exception"

Malheureusement, cette approche échoue car la méthode "start" retourne immédiatement, provoquant l'apparition de l'exception dans le contexte du thread enfant. La trace de la pile d'exceptions reste isolée dans ce thread, la rendant inaccessible au thread appelant.

Résoudre l'exception

Pour résoudre ce problème, une approche prometteuse consiste à utiliser la transmission de messages. En utilisant une file d'attente de messages, les exceptions peuvent être communiquées du thread enfant au thread appelant. Voici un exemple d'implémentation :

import sys
import threading
import queue


class ExcThread(threading.Thread):

    def __init__(self, bucket):
        threading.Thread.__init__(self)
        self.bucket = bucket

    def run(self):
        try:
            raise Exception('An error occured here.')
        except Exception:
            self.bucket.put(sys.exc_info())


def main():
    bucket = queue.Queue()
    thread_obj = ExcThread(bucket)
    thread_obj.start()

    while True:
        try:
            exc = bucket.get(block=False)
        except queue.Empty:
            pass
        else:
            exc_type, exc_obj, exc_trace = exc
            # deal with the exception
            print exc_type, exc_obj
            print exc_trace

        thread_obj.join(0.1)
        if thread_obj.isAlive():
            continue
        else:
            break


if __name__ == '__main__':
    main()

Explication :

  • ExcThread : une classe de thread personnalisée qui place les informations d'exception dans une file d'attente de messages nommée bucket.
  • main : Le thread appelant qui vérifie en permanence la file d'attente pour les exceptions à l'aide d'une opération get non bloquante.
  • exc_type, exc_obj, exc_trace : contenu de l'exception récupérée qui peut être géré en conséquence.

Conclusion

En employant des techniques de transmission de messages, il devient possible de capturer les exceptions d'un thread enfant et de les gérer efficacement dans le thread appelant. Cela permet aux développeurs de résoudre rapidement les erreurs potentielles, conduisant ainsi à des applications multithread plus robustes et plus réactives.

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:
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