Depurar multiprocessamento em Python

14

Quais são algumas boas práticas na depuração de programas de multiprocessamento no Python?

vonPetrushev
fonte

Respostas:

6

Os verdadeiros programas Python de multiprocessamento (em oposição aos programas Python multiencadeados que precisam lidar com o temido GIL ) não são diferentes dos de qualquer outra linguagem. Todos eles têm os mesmos desafios básicos:

  1. Designação de tarefas e relatórios de resultados. Mesmo que eles estejam trabalhando principalmente em conjuntos de dados independentes, normalmente precisam voltar ao thread principal para relatar resultados e obter novos dados para trabalhar. Este pode ser um ponto de estrangulamento.
  2. Condições da corrida. Os processos estão tentando usar um recurso de cada vez e precisam usar o mutex (ou algo semelhante) para não passar por todos os dados um do outro. A falha em proteger esses tipos de recursos pode levar a sessões de depuração realmente dolorosas.
  3. Sequencialidade. Às vezes você está tentando fazer algo paralelo que não é. Os vários processos acabam esperando um pelo outro fazer alguma coisa e o resultado final é que você, para todos os efeitos, tomou um programa seqüencial, o tornou paralelo e ainda termina em execução em tempo linear (ou pior).

Embora existam métodos de desenvolvimento que tentem evitar cada um desses problemas, no final do dia você realmente precisa pensar no que está fazendo. Eu recomendo testes de estresse intensos - muito além de tudo que você acha que pode acontecer na vida real - para que você tenha uma boa chance de acessar o Windows of Opportunity e explodir no desenvolvimento, em vez de no meio de uma grande demonstração ou durante a produção.

Nós costumávamos usar arquivos de log microssegundo-timestamped e, em seguida, criou um log aplicativo de visualização com código de cores para que pudéssemos tentar visualizar o que estava acontecendo entre o processo N rodando em processadores M. Também tentamos (e principalmente conseguimos) criar um sistema que afastasse os arquivos de log para recriar o contexto da falha.

Mas a melhor ferramenta é um bom design e pessoas realmente más e desagradáveis ​​que tentam tirar seu aplicativo da água. (Oi, dbell!)

Peter Rowell
fonte
25

Uma coisa que eu acho muito útil é usar o registrador existente no multiprocessingmódulo. Tente isso no seu código principal:

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

Veja também: http://docs.python.org/library/multiprocessing.html#logging

Além disso, você pode acessar o nome do processo atual usando:

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

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

Além disso, não sei de mais nada, exceto os métodos de depuração padrão, como o pdb& co.

exuma
fonte