Programación concurrente con Python
Monitores
Es posible disponer de monitores SC en Python, se estructuran en torno a la clase Condition
. Un objeto de clase Condition
soporta un cerrojo y un único wait-set
.
Es un modelo similar al de monitores en Java con el API de concurrencia estándar, es por tanto, obligado el uso de condiciones de guarda.
Este modelo de hebras...
Python utiliza el Global Interpreter Lock (GIL). Los cual imposibilita el paralelismo real, olbiga a las hebras a ejecutarse secuencialmente e imposibilita ligrar speedups
mayores a 1.
Concurrencia con procesos
Alternativa a threading
y el GIL, usando el módulo multiprocessing
. Libre del GIL → concurrencia real, pero a diferencia de las hebras los procesos no comportan memoria, se necesitan medios específicos (IPC) para compartir la memoria.
Instanciar un proceso rápidamente
Utilizando el contructor de la clase Process
, recibe dos parámetros:
- Una función/método con el código que el proceso debe ejecutar
- La lista de parámetros que la función/método necesita
multiprocessing.Process(target=miFuncion, args=(arg1, arg2,..., argn))
multiprocessing
crea dos intérpretes de python
Comunicación entre procesos
Existen dos técnicas para comunicar procesos, no se basan en el paradigma de memoria compartida, se basan en el paradigma de paso de mensajes.
Esto requiere tipo de estructura de datos ad-hoc como los cauces (pipes) o las colas. Básicamente son memorias accesibles para varios procesos, que deben crearse explícitamente, y que suelen residir en el espacio del kernel.
Comunicación con pipes
Un cauce, pipe, es una zona de memoria del kernel, puede ser leída y escrita por varios procesos. Se basan en el paradigma de paso de mensajes, la comunicación utiliza send-receive.
Comunicación con colas
Una cola es una estructura de datos FIFO compartida entre procesos, se gestiona con los métodos put
y get
. Es muy parecido a utilizar contenedores autosincronizados en Java.
Procesos y ejecutores
El módulo multiprocessing
permite utilizar un ejecutor de procesos, es ejecutor es dimensionable. Utiliza el método map()
para enviar procesos al ejecutor.
Sincronización de procesos
Es posible sincronizar procesos de forma estándar, el módulo multiprocessing
ofrece las clases Lock
, Barrier
y Condition
.
Sin embargo, puesto que Python con procesos no utiliza un paradigma de memoria compartida, sino un paradigma de paso mensajes, el modelo de sincronización estándar con estas clases apenas se utiliza.