paralelismo - pool python example
¿Cuál es la mejor manera de obtener un seguimiento de pila cuando se utiliza el multiprocesamiento? (3)
Python 2
He hecho una implementación de decorador de la siguiente manera. Tenga en cuenta el uso de functools.wraps
, de lo contrario el multiprocessing
fallaría.
def full_traceback(func):
import traceback, functools
@functools.wraps(func)
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except Exception as e:
msg = "{}/n/nOriginal {}".format(e, traceback.format_exc())
raise type(e)(msg)
return wrapper
Puede encontrar un ejemplo en https://stackoverflow.com/a/43223455 .
Python 3
Como lo menciona Paige Lo , ahora el método get
de multiprocessing.pool.Async
devuelve el rastreo completo en Python 3, consulte http://bugs.python.org/issue13831 .
Me pregunto cuál es la mejor manera de obtener un seguimiento de pila cuando hay una excepción dentro de una función ejecutada a través del módulo de multiprocesamiento. Aquí hay un ejemplo:
import multiprocessing
def square(x):
raise Exception("Crash.")
return x**2
if __name__ == ''__main__'':
pool = multiprocessing.Pool(processes=4)
results = pool.map_async(square, range(5))
for result in results.get():
print result
Esto imprime:
Traceback (most recent call last):
File "/extra/workspace/Playground/src/multiproc/multiproc_debug.py", line 11, in <module>
for result in results.get():
File "/extra/Python 2.6/lib/python2.6/multiprocessing/pool.py", line 422, in get
raise self._value
Exception: Crash.
Así que no hay un stacktrace útil, lo cual es bastante molesto. Mi solución actual para esto:
import multiprocessing
import traceback
def square(x):
try:
# some more code...
raise Exception("Crash.")
except Exception, exception:
print exception
traceback.print_exc()
raise
return x**2
¿Hay una manera de obtener este comportamiento sin todo el código de boilerplate? Si no es así, ¿cuál es la razón para no incluir esta función?
Edición: Se podría usar un decorador para el código de la placa de la caldera, pero no sé si ese decorador está incluido en la biblioteca estándar.
En Python 3.4, se proporciona el rastreo completo.
Parece que deberías evitar subir la excepción desde tu función principal. En su lugar, puede atraparlo, tratarlo como un valor devuelto al programa principal y luego subirlo allí. Volver a lanzar excepciones en Python tiene más detalles.