Maison  >  Article  >  développement back-end  >  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 ?

Susan Sarandon
Susan Sarandonoriginal
2024-10-22 14:22:03252parcourir

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 :

<code class="python">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()</code>

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 :

<code class="python">    results = pool.map(slowly_square, range(40))</code>

par :

<code class="python">    results = pool.map_async(slowly_square, range(40)).get(9999999)</code>

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

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