Varios threads ejecutan counter += 1 sobre una variable global compartida, 1 millón de veces cada uno. ¿El GIL garantiza que el total final sea correcto?
Opciones
- Sí, el GIL hace que
counter += 1sea un único paso atómico - No,
+=son varios pasos y los threads pueden intercalarse entre ellos (Opción correcta) - Sí, pero solo en Linux, donde el GIL es más estricto
- No, Python prohíbe compartir una variable global entre threads
Respuesta
No, += es una lectura, modificación y escritura de varios bytecodes, y los threads pueden intercalarse
Por qué
El GIL protege las partes internas de Python, no tu lógica. counter += 1 son varios pasos pequeños: leer counter, sumar 1, escribirlo de vuelta.
Un thread puede pausarse entre la lectura y la escritura. Mientras tanto otro thread actualiza el contador, y luego el primero escribe un valor antiguo: se pierde una actualización. Esto es una race condition.
Protege los datos compartidos con un Lock.
lock = threading.Lock()
def work():
global counter
for _ in range(1_000_000):
with lock:
counter += 1Recuerda
El GIL no es thread safety. Usa un Lock para datos compartidos.