Compartición de Datos
from multiprocessing import Process, Lock, Manager
def modificar_contador(contador, candado):
with candado:
contador['valor'] -= 1
if __name__ == '__main__':
with Manager() as administrador:
candado = Lock()
contador_compartido = administrador.dict({'valor': 10})
procesos = []
for i in range(10):
p = Process(target=modificar_contador, args=(contador_compartido, candado))
procesos.append(p)
p.start()
for p in procesos:
p.join()
print(contador_compartido)
Fundamentos de Hilos y Bloqueo GIL
- Procesos: Aislamiento de datos, unidad mínima de asignación de recursos, utilizan múltiples núcleos, gestionados por el SO, alta sobrecarga en creación/cierre
- Número típico: no superar el doble de núcleos CPU
- Uso básico:
start() y join()
- Problemas de seguridad:
Lock
- Comunicación entre procesos (IPC):
- Colas (seguras), tuberías (inseguras)
- Herramientas externas
- Compartición de datos mediante
Manager
- Modelo productor-consumidor
- Hilos: Unidad mínima programable por el SO
- Comparten datos entre sí
- Baja sobrecarga en creación/cierre
- Limitaciones en CPython por GIL
GIL en CPython
- No permite uso de múltiples núcleos para hilos
- Mecanismo de recolección de basura:
- Conteo de refeerncias + recolección generacional
- Bloqueo de Intérprete Global (GIL) asegura precisión en conteo de referencias
- Restringe ejecución a un único hilo por proceso en CPU
- Optimiza tiempo de operaciones I/O, no cómputo CPU
Alternativas de Intérprete
- PyPy: Mantiene limitaciones de GIL
- JPython: Permite uso de múltiples núcleos
Módulo Threading
enumerate(): Lista de objetos de hilos activos
active_count(): Cantidad de hilos activos
current_thread(): Obtiene hilo actual (ident devuelve ID)
import time
from threading import Thread, current_thread
import os
def tarea(indice):
print(f'inicio{indice}', current_thread().ident)
time.sleep(1)
print(f'fin{indice}')
if __name__ == '__main__':
hilos = []
for i in range(10):
h = Thread(target=tarea, args=(i,))
h.start()
print(h.ident, os.getpid())
hilos.append(h)
for h in hilos:
h.join()
print('Ejecución completada')
Hilos con Orientación a Objetos
from threading import Thread
class HiloPersonalizado(Thread):
def __init__(self, param1, param2):
self.param1 = param1
self.param2 = param2
super().__init__()
def run(self):
print(self.ident, self.param1, self.param2)
h = HiloPersonalizado(1, 2)
h.start()
print(h.ident)
Compartición de Datos entre Hilos
from threading import Thread
valor_global = 100
def reducir():
global valor_global
valor_global -= 1
hilos = []
for _ in range(100):
h = Thread(target=reducir)
h.start()
hilos.append(h)
for h in hilos:
h.join()
print(valor_global) # Resultado: 0