Resuelve las race conditions con Lock, coordina threads con Event y aprende a reconocer y evitar deadlocks.
| Lock | Event | |
|---|---|---|
| Propósito | Proteger recurso compartido | Señalizar que algo ocurrió |
| Cuántos pasan | Solo 1 thread a la vez | Todos los threads en wait() |
| Se resetea | Al hacer release() | Solo con clear() explícito |
| Uso típico | Sección crítica | Inicio coordinado, notificaciones |
import threading evento_a = threading.Event()evento_b = threading.Event() def tarea_1(): evento_b.wait() # espera que T2 active evento_b evento_a.set() # activa evento_a para T2 def tarea_2(): evento_a.wait() # espera que T1 active evento_a evento_b.set() # activa evento_b para T1 t1 = threading.Thread(target=tarea_1)t2 = threading.Thread(target=tarea_2)t1.start()t2.start()# T1 espera evento_b → pero T2 nunca lo activa porque espera evento_a# T2 espera evento_a → pero T1 nunca lo activa porque espera evento_b# → deadlocklock_a antes que lock_b), la espera circular es imposible.Si tu programa se congela sin imprimir nada y sin error, sospecha de un deadlock. Agrega prints antes de cada acquire/wait para identificar cuál thread está bloqueado y qué espera.