Déboguer le multitraitement en Python

Réponses:

6

Les vrais programmes Python multiprocesseurs (par opposition aux programmes Python multithread qui doivent gérer le redoutable GIL ) ne sont pas différents de ceux de n'importe quel autre langage. Ils ont tous les mêmes défis de base:

  1. Affectation des tâches et rapport des résultats. Même s'ils travaillent principalement sur des ensembles de données indépendants, ils doivent normalement retourner au thread principal pour rendre compte des résultats et obtenir de nouvelles données sur lesquelles travailler. Cela peut être un point d'étranglement.
  2. Conditions de course. Les processus essaient d'utiliser une ressource à la fois et ils doivent utiliser mutex (ou quelque chose de similaire) pour éviter de se déplacer les uns sur les autres. Ne pas protéger ces types de ressources peut conduire à des sessions de débogage vraiment, vraiment pénibles.
  3. Séquentialité. Parfois, vous essayez de faire quelque chose de parallèle qui ne l'est pas. Les différents processus finissent par attendre que les uns et les autres fassent quelque chose et le résultat final est que vous avez, à toutes fins utiles, pris un programme séquentiel, rendu parallèle, et qu'il finit toujours par s'exécuter en temps linéaire (ou pire).

Bien qu'il existe des méthodes de développement qui essaient d'éviter chacun de ces problèmes, à la fin de la journée, vous devez vraiment réfléchir à ce que vous faites. Je recommande des tests de résistance lourds - bien au-delà de tout ce qui pourrait se produire dans la vie réelle - afin que vous ayez de bonnes chances de frapper ces fenêtres d'opportunité et de exploser en cours de développement, par opposition à une démo majeure ou pendant la production.

Nous avions l'habitude d'utiliser des fichiers journaux horodatés en microsecondes, puis nous avons créé une application d'affichage des journaux à code couleur afin que nous puissions essayer de visualiser ce qui se passait entre les processus N exécutés sur M processeurs. Nous avons également essayé (et surtout réussi) à créer un système qui chasserait les fichiers journaux pour recréer le contexte de l'accident.

Mais le meilleur outil est un bon design et des gens vraiment méchants et méchants qui essaient de faire sauter votre application hors de l'eau. (Salut, dbell!)

Peter Rowell
la source
25

Une chose que je trouve très utile, c'est d'utiliser l'enregistreur existant dans le multiprocessingmodule. Essayez ceci dans votre code principal:

import multiprocessing, logging
mpl = multiprocessing.log_to_stderr()
mpl.setLevel(logging.INFO)

Voir également: http://docs.python.org/library/multiprocessing.html#logging

De plus, vous pouvez accéder au nom du processus actuel en utilisant:

cpname = multiprocessing.current_process().name
# print cpname
mylogger.info("{0} is currently doing...".format(cpname))

Voir: http://docs.python.org/library/multiprocessing.html#multiprocessing.current_process

En dehors de cela, je ne connais rien d'autre que les méthodes de débogage standard comme pdb& co.

exhuma
la source