Hay varias implementaciones de Python, por ejemplo, CPython, IronPython, RPython, etc.
Algunos de ellos tienen un GIL, otros no. Por ejemplo, CPython tiene la GIL:
De enlace
Las aplicaciones escritas en lenguajes de programación con un GIL pueden diseñarse para usar procesos separados para lograr un paralelismo completo, ya que cada proceso tiene su propio intérprete y, a su vez, tiene su propio GIL.
Beneficios de la GIL
- Mayor velocidad de los programas de un solo hilo.
- Fácil integración de bibliotecas de C que normalmente no son seguras para subprocesos.
Por qué Python (CPython y otros) usa la GIL
En CPython, el bloqueo global del intérprete, o GIL, es un mutex que impide que varios subprocesos nativos ejecuten códigos de bytes de Python a la vez. Este bloqueo es necesario principalmente porque la administración de memoria de CPython no es segura para subprocesos.
El GIL es controvertido porque evita que los programas de multiproceso de CPython aprovechen al máximo los sistemas multiprocesador en ciertas situaciones. Tenga en cuenta que las operaciones de bloqueo o de ejecución prolongada, como E / S, procesamiento de imágenes y procesamiento de números NumPy, ocurren fuera de la GIL. Por lo tanto, es solo en programas de multiproceso que pasan mucho tiempo dentro de la GIL, interpretando el código de byte de CPython, que la GIL se convierte en un cuello de botella.
Python tiene un GIL en lugar de un bloqueo de grano fino por varias razones:
-
Es más rápido en el caso de un solo hilo.
-
Es más rápido en el caso de subprocesos múltiples para programas enlazados de E / S.
-
Es más rápido en el caso de subprocesos múltiples para programas ligados a cpu que hacen su trabajo intensivo de cómputo en bibliotecas de C
-
Hace que las extensiones C sean más fáciles de escribir: no habrá ningún cambio de subprocesos de Python, excepto cuando permitas que esto suceda (es decir, entre las macros Py_BEGIN_ALLOW_THREADS y Py_END_ALLOW_THREADS).
-
Hace que el ajuste de las bibliotecas de C sea más fácil. No tienes que preocuparte por la seguridad de los hilos. Si la biblioteca no es segura para subprocesos, simplemente mantendrá la GIL bloqueada mientras la llama.
El GIL puede ser liberado por las extensiones C. La biblioteca estándar de Python libera el GIL alrededor de cada llamada de I / O de bloqueo. Por lo tanto, GIL no tiene ninguna consecuencia para el rendimiento de los servidores enlazados de E / S. Por lo tanto, puede crear servidores de red en Python usando procesos (bifurcación), subprocesos o i / o asíncrono, y GIL no se interpondrá en su camino.
Las bibliotecas numéricas en C o Fortran se pueden llamar de manera similar con el GIL liberado. Mientras su extensión C está esperando que se complete una FFT, el intérprete ejecutará otros subprocesos de Python. Por lo tanto, un GIL es más fácil y más rápido que el bloqueo de grano fino en este caso. Esto constituye el grueso del trabajo numérico. La extensión NumPy libera la GIL siempre que sea posible.
Los subprocesos suelen ser una mala forma de escribir la mayoría de los programas de servidor. Si la carga es baja, forking es más fácil. Si la carga es alta, la I / O asíncrona y la programación controlada por eventos (por ejemplo, utilizando el marco Twisted de Python) es mejor. La única excusa para usar hilos es la falta de os.fork en Windows.
La GIL es un problema si, y solo si, está haciendo un trabajo intensivo de CPU en Python puro. Aquí puede obtener un diseño más limpio utilizando procesos y paso de mensajes (por ejemplo, mpi4py). También hay un módulo de 'procesamiento' en Python Cheese Shop, que le da a los procesos la misma interfaz que los hilos (es decir, reemplazar los hilos. Hilo con procesamiento.Proceso).
Los subprocesos se pueden usar para mantener la capacidad de respuesta de una GUI independientemente de la GIL. Si la GIL afecta su rendimiento (consulte la discusión anterior), puede dejar que su hilo genere un proceso y esperar a que termine.