Los «garantías» cambiantes que ofrece el Global Interpreter Lock de Python

El Global Interpreter Lock (GIL) de Python se está reconsiderando, lo que plantea preguntas sobre qué garantías de seguridad para hilos ofrece realmente Python y qué no ha sido más que un accidente de la implementación de CPython. Los comentaristas debaten si depender del GIL para operaciones atómicas es un diseño “roto” o una práctica de facto estándar en un ecosistema sin una especificación formal del lenguaje, y qué obligaciones tienen los desarrolladores centrales de no “romper el espacio de usuario” mientras avanzan hacia compilaciones opcionales sin GIL. Muchos ven el bloqueo por objeto y una documentación más clara sobre qué es realmente atómico como un cambio necesario pero arriesgado, que intercambia algo de rendimiento monohilo y seguridad implícita por un mejor aprovechamiento de varios núcleos y una semántica de concurrencia más predecible.

Alcance del GIL y garantías de atomicidad

  • Muchos sostienen que tratar como verdaderamente seguras para hilos las “cosas que el GIL hace parecer atómicas” es un diseño roto; deberían usarse primitivas de sincronización adecuadas.
  • Otros contraargumentan que, cuando la mayor parte del ecosistema depende de un comportamiento, este se convierte en un estándar de facto, lo que hace los cambios extremadamente difíciles (Ley de Hyrum, “no rompas el espacio de usuario”).
  • Aclaración: el GIL protege principalmente los datos internos del intérprete, no las condiciones de carrera a nivel de usuario. Código como x = self._next_id; self._next_id += 1 hoy no es seguro para hilos en términos de comportamiento; solo es seguro para la memoria.
  • Algunas operaciones de list/dict están documentadas explícitamente como atómicas (p. ej., D[x] = y), y la gente depende de ello; preservar tales garantías en un mundo sin GIL se considera crucial.

Planes y preocupaciones en torno a eliminar el GIL

  • Las futuras compilaciones --disable-gil/nogil usarán bloqueos de grano fino por objeto; las mutaciones típicas de list/dict no deberían provocar fallos de segmentación y, a menudo, seguirán siendo atómicas.
  • Ejemplo dado: llamadas concurrentes a list.extend producirán o bien un resultado completo A-luego-B o B-luego-A, no una intercalación, bajo nogil.
  • Sobrecarga: se informa que el bloqueo adicional ralentiza el código monohilo en aproximadamente un 5–10%; algunos temen que “bloquear cada escritura mutable” será “lento”, otros dicen que los bloqueos sin contención son baratos.
  • Existe preocupación sobre qué operaciones tendrán garantizada la atomicidad y cuáles no, especialmente donde intervienen iteradores y código de usuario. Se espera una mejor documentación sobre seguridad para hilos, pero todavía “es mucho trabajo”.

Semántica de Python, especificación y detalles de implementación

  • Fuerte debate sobre si Python tiene una “especificación”:
    • Un bando: la Language Reference más los PEP constituyen una especificación de facto que distingue entre garantías del lenguaje y detalles propios de CPython (p. ej., GIL, conteo de referencias).
    • El otro bando: es descriptiva, no una norma formal; la verdadera referencia es el propio CPython, y el GIL forma parte de la semántica de Python en la práctica.
  • Las implementaciones alternativas (PyPy, Jython, IronPython, MicroPython, etc.) divergen de varias maneras, lo que refuerza que ciertos comportamientos de CPython (como el GIL) no pueden considerarse características obligatorias del lenguaje.

Impacto práctico y casos de uso

  • Algunos desarrolladores web y vinculados a E/S informan que nunca han estado limitados por el GIL; la concurrencia por hilos principalmente oculta la latencia de E/S.
  • Otros en contextos de CPU intensiva, procesamiento de datos y ML consideran el GIL un obstáculo importante, y recurren a multiprocessing con sobrecostes de serialización.
  • Se sugieren opciones como mantener un modo compatible con GIL e incluso pasar a “Python 4” para un modelo sin GIL, reflejando la escala del cambio semántico y del ecosistema.

Digresión sobre versionado

  • Discusión lateral sobre el estilo 3.9 frente a 3.13 de Python: los componentes de versión son enteros separados por puntos, no decimales.
  • Esto se presenta como una estructura común, tipo semver, aunque las versiones “menores” de Python aún pueden introducir cambios incompatibles.