"Si un ouvrier veut bien faire son travail, il doit d'abord affûter ses outils." - Confucius, "Les Entretiens de Confucius. Lu Linggong"
Page de garde > La programmation > Comment gérer les interruptions de clavier dans le pool multitraitement de Python ?

Comment gérer les interruptions de clavier dans le pool multitraitement de Python ?

Publié le 2024-12-22
Parcourir:175

How to Handle Keyboard Interrupts in Python\'s Multiprocessing Pool?

Gestion des interruptions clavier dans le pool multitraitement de Python

Dans le module multitraitement de Python, la classe Pool offre un moyen pratique de répartir les tâches sur plusieurs processus. Cependant, la gestion des événements KeyboardInterrupt dans les pools peut être difficile, comme le démontre l'extrait de code :

from multiprocessing import Pool
from time import sleep
from sys import exit

def slowly_square(i):
    sleep(1)
    return i*i

def go():
    pool = Pool(8)
    try:
        results = pool.map(slowly_square, range(40))
    except KeyboardInterrupt:
        # **** THIS PART NEVER EXECUTES. ****
        pool.terminate()
        print "You cancelled the program!"
        sys.exit(1)
    print "\nFinally, here are the results: ", results

if __name__ == "__main__":
    go()

Lors de l'exécution de ce code, appuyer sur Ctrl C ne déclenchera pas le processus de nettoyage, laissant les sous-processus s'exécuter indéfiniment. Pour résoudre ce problème, envisagez la solution de contournement suivante :

Le comportement observé dans le code est une conséquence d'un bug Python. KeyboardInterrupt n'est pas envoyé lors de l'attente d'une condition dans threading.Condition.wait(). Comme Pool.map() utilise une condition d'attente en interne, l'interruption n'est jamais reçue.

Une solution consiste à utiliser Pool.map_async(), qui permet de spécifier un timeout. En définissant un délai d'attente suffisamment long (par exemple, 9999999), nous pouvons garantir que l'interruption sera déclenchée dans un délai raisonnable.

Par conséquent, remplacez :

    results = pool.map(slowly_square, range(40))

avec :

    results = pool.map_async(slowly_square, range(40)).get(9999999)

Cette solution de contournement fournit un moyen de gérer correctement les événements KeyboardInterrupt dans les pools multitraitements, permettant l'arrêt de tous les sous-processus lorsque l'utilisateur annule le programme.

Déclaration de sortie Cet article est réimprimé à l'adresse : 1729576640. En cas d'infraction, veuillez contacter [email protected] pour le supprimer.
Dernier tutoriel Plus>

Clause de non-responsabilité: Toutes les ressources fournies proviennent en partie d'Internet. En cas de violation de vos droits d'auteur ou d'autres droits et intérêts, veuillez expliquer les raisons détaillées et fournir une preuve du droit d'auteur ou des droits et intérêts, puis l'envoyer à l'adresse e-mail : [email protected]. Nous nous en occuperons pour vous dans les plus brefs délais.

Copyright© 2022 湘ICP备2022001581号-3