Multiprocesamiento vs subprocesos Python [duplicado]
Estoy tratando de comprender las ventajas del multiprocesamiento sobre el subprocesamiento . Sé que el multiprocesamiento evita el bloqueo global del intérprete, pero ¿qué otras ventajas existen? ¿ Los subprocesos no pueden hacer lo mismo?
Aquí hay algunos pros y contras que se me ocurrieron.
Multiprocesamiento
Ventajas
- Espacio de memoria separado
- El código suele ser sencillo
- Aprovecha múltiples CPU y núcleos
- Evita las limitaciones de GIL para cPython
- Elimina la mayoría de las necesidades de primitivas de sincronización a menos que use memoria compartida (en cambio, es más un modelo de comunicación para IPC)
- Los procesos secundarios son interrumpibles/eliminables
- El módulo Python
multiprocessing
incluye abstracciones útiles con una interfaz muy parecidathreading.Thread
- Imprescindible con cPython para el procesamiento vinculado a la CPU
Contras
- IPC un poco más complicado con más gastos generales (modelo de comunicación versus memoria/objetos compartidos)
- Mayor huella de memoria
Enhebrado
Ventajas
- Ligero: ocupa poca memoria
- Memoria compartida: facilita el acceso al estado desde otro contexto
- Le permite crear fácilmente interfaces de usuario responsivas
- Los módulos de extensión de cPython C que liberan correctamente el GIL se ejecutarán en paralelo
- Gran opción para aplicaciones vinculadas a E/S
Contras
- cPython - sujeto al GIL
- No interrumpible/matable
- Si no se sigue un modelo de cola de comandos/bomba de mensajes (usando el
Queue
módulo), entonces el uso manual de primitivas de sincronización se convierte en una necesidad (se necesitan decisiones para la granularidad del bloqueo) - El código suele ser más difícil de entender y corregir: el potencial de condiciones de carrera aumenta dramáticamente
El threading
módulo usa subprocesos, el multiprocessing
módulo usa procesos. La diferencia es que los subprocesos se ejecutan en el mismo espacio de memoria, mientras que los procesos tienen memoria separada. Esto hace que sea un poco más difícil compartir objetos entre procesos con multiprocesamiento. Dado que los subprocesos utilizan la misma memoria, se deben tomar precauciones o dos subprocesos escribirán en la misma memoria al mismo tiempo. Para esto sirve el bloqueo global del intérprete.
Los procesos de generación son un poco más lentos que los hilos de generación.
El trabajo de Threading es permitir que las aplicaciones respondan. Suponga que tiene una conexión a una base de datos y necesita responder a la entrada del usuario. Sin subprocesos, si la conexión a la base de datos está ocupada, la aplicación no podrá responder al usuario. Al dividir la conexión de la base de datos en un hilo separado, puede hacer que la aplicación responda mejor. Además, debido a que ambos subprocesos están en el mismo proceso, pueden acceder a las mismas estructuras de datos: buen rendimiento, además de un diseño de software flexible.
Tenga en cuenta que debido a GIL, la aplicación en realidad no está haciendo dos cosas a la vez, pero lo que hemos hecho es colocar el bloqueo de recursos en la base de datos en un subproceso separado para que el tiempo de CPU se pueda cambiar entre él y la interacción del usuario. El tiempo de CPU se raciona entre los subprocesos.
El multiprocesamiento es para momentos en los que realmente desea que se haga más de una cosa en un momento dado. Suponga que su aplicación necesita conectarse a 6 bases de datos y realizar una transformación matricial compleja en cada conjunto de datos. Poner cada trabajo en un hilo separado podría ayudar un poco porque cuando una conexión está inactiva, otra podría obtener algo de tiempo de CPU, pero el procesamiento no se realizaría en paralelo porque el GIL significa que solo estás usando los recursos de una CPU. . Al colocar cada trabajo en un proceso de multiprocesamiento, cada uno puede ejecutarse en su propia CPU y funcionar con total eficiencia.