multiproceso o enhebrado en python?

Tengo una aplicación de python que toma una colección de datos y para cada parte de los datos de esa colección realiza una tarea. La tarea tarda algún tiempo en completarse, ya que hay un retraso involucrado. Debido a este retraso, no quiero que cada parte de los datos realice la tarea posteriormente, quiero que todos sucedan en paralelo. ¿Debo estar usando multiproceso? ¿O roscado para esta operación?

Intenté usar hilos, pero tuve algunos problemas, a menudo algunas de las tareas nunca se disparaban.

Si está realmente vinculado al cálculo, el uso del módulo de multiprocesamiento es probablemente la solución más liviana (en términos de consumo de memoria y dificultad de implementación).

Si está enlazado a E / S, el uso del módulo de subprocesamiento generalmente le dará buenos resultados. Asegúrese de usar almacenamiento seguro de subprocesos (como la Cola) para entregar los datos a sus subprocesos. O bien, entrégueles un único dato que sea único para ellos cuando se generen.

PyPy se centra en el rendimiento. Tiene una serie de características que pueden ayudar con el procesamiento de cómputo. También tienen soporte para Software Transactional Memory, aunque todavía no es de calidad de producción. La promesa es que puede usar mecanismos paralelos o concurrentes más simples que el multiprocesamiento (que tiene algunos requisitos incómodos).

Python sin stack también es una buena idea. Stackless tiene problemas de portabilidad como se indica arriba. Unladen Swallow fue prometedor, pero ahora está difunto. Pyston es otra implementación de Python (sin terminar) que se centra en la velocidad. Está adoptando un enfoque diferente a PyPy, que puede dar lugar a mejoras (o simplemente diferentes) aceleraciones.

Las tareas se ejecutan secuencialmente, pero tienes la ilusión de que se ejecutan en paralelo. Las tareas son buenas cuando se usa para E / S de archivos o conexiones y porque son ligeros.

Multiprocess with Pool puede ser la solución adecuada para usted porque los procesos se ejecutan en paralelo, por lo que son muy buenos con la computación intensiva porque cada proceso se ejecuta en una CPU (o núcleo).

La configuración del multiprocesamiento puede ser muy fácil:

from multiprocessing import Pool def worker(input_item): output = do_some_work() return output pool = Pool() # it make one process for each CPU (or core) of your PC. Use "Pool(4)" to force to use 4 processes, for example. list_of_results = pool.map(worker, input_list) # Launch all automatically 

Para pequeñas colecciones de datos, simplemente cree subprocesos con subprocess.Popen .

Cada subproceso puede simplemente obtener su parte de los datos desde los stdin o desde los argumentos de la línea de comandos, hacer su procesamiento y simplemente escribir el resultado en un archivo de salida.

Cuando todos los subprocesos hayan finalizado (o se hayan agotado), simplemente se fusionan los archivos de salida.

Muy simple.

Puedes considerar mirar Python sin stack . Si tiene el control sobre la función que lleva mucho tiempo, puede lanzar un poco de stackless.schedule() s allí (diciendo rendimiento a la próxima rutina), o bien puede configurar Stackless para realizar tareas múltiples preventivas .

En Stackless, no tiene subprocesos, sino tasklets o greenlets que son esencialmente subprocesos muy ligeros. Funciona muy bien en el sentido de que hay un marco bastante bueno con muy poca configuración para que la multitarea funcione.

Sin embargo, Stackless dificulta la portabilidad porque debe reemplazar algunas de las bibliotecas estándar de Python: Stackless elimina la dependencia de la stack de C. Es muy portátil si el siguiente usuario también tiene instalado Stackless, pero rara vez será así.

El uso del modelo de subprocesos de CPython no le proporcionará ninguna mejora en el rendimiento, ya que los subprocesos no se ejecutan en paralelo, debido a la forma en que se maneja la recolección de basura. El multiprocesamiento permitiría la ejecución paralela. Obviamente, en este caso, debe tener varios núcleos disponibles para agrupar sus trabajos paralelos.

Hay mucha más información disponible en esta pregunta relacionada .

Si puede particionar y separar fácilmente los datos que tiene, parece que debería hacer esa partición externamente y enviarlos a varios procesos de su progtwig. (es decir, varios procesos en lugar de hilos)

IronPython tiene multihilo real, a diferencia de CPython y es GIL. Así que, dependiendo de lo que estés haciendo, vale la pena mirar. Pero parece que su caso de uso se adapta mejor al módulo de multiprocesamiento.

Para el tipo que recomienda python sin stack, no soy un experto en eso, pero me parece que está hablando de software “multithreading”, que en realidad no es paralelo en absoluto (todavía se ejecuta en un hilo físico, por lo que no puede escalar a múltiples núcleos.) Es simplemente una forma alternativa de estructurar aplicaciones asíncronas (pero aún de un solo hilo, no paralelas).

Es posible que desee mirar Twisted . Está diseñado para tareas de red asíncronas.