logo

¿Qué es GIL en Python? Bloqueo global de intérprete

Este tutorial se centrará en uno de los temas importantes de Python, GIL. También cubriremos cómo el GIL afecta el rendimiento de los programas Python con la implementación del código. Antes de profundizar en este tema, tengamos una idea básica del GIL.

GIL o bloqueo global de intérprete

Python Global Interpreter Lock o GIL es una parte importante de la programación multiproceso. Es un tipo de bloqueo de proceso que se utiliza cuando se trabaja con múltiples procesos. Le da el control a un solo hilo. Generalmente, Python usa un solo hilo para ejecutar un solo proceso. Obtenemos el mismo resultado de rendimiento de los procesos de un solo subproceso y de múltiples subprocesos utilizando GIL. Restringe la realización de subprocesos múltiples en Python porque evita los subprocesos y funciona como un solo subproceso.

Nota: Python no admite subprocesos múltiples porque los paquetes de subprocesos no nos permiten usar múltiples núcleos de CPU.

¿Por qué los desarrolladores de Python utilizan GIL?

Python proporciona la función única de contador de referencias, que se utiliza para la gestión de la memoria. El contador de referencias cuenta el número total de referencias realizadas internamente en Python para asignar un valor a un objeto de datos. Cuando los recuentos de referencias llegan a cero, se libera la memoria asignada del objeto. Veamos el siguiente ejemplo.

Ejemplo -

cómo obtener una fecha actual en java
 import sys a = [] b = a sys.getrefcount(a) 

La principal preocupación con la variable de recuento de referencias es que puede verse afectada cuando dos o tres subprocesos intentan aumentar o disminuir su valor simultáneamente. Se conoce como condición de carrera. Si se produce esta condición, puede deberse a una pérdida de memoria que nunca se libera. Puede fallar o errores en el programa Python.

GIL nos ayuda a eliminar esta situación mediante el uso de bloqueos en todas las estructuras de datos compartidas entre subprocesos para que no se modifiquen de manera inconsistente. Python proporciona una manera sencilla de implementar GIL, ya que se ocupa de la gestión de memoria segura para subprocesos. GIL requiere ofrecer un único bloqueo a un hilo para su procesamiento en Python. Aumenta el rendimiento de un programa de un solo subproceso, ya que solo es necesario manejar un bloqueo. También ayuda a crear cualquier programa vinculado a la CPU y previene la condición de interbloqueo.

int a cadena java

El impacto en los programas Python multiproceso

Existe una diferencia entre los límites de la CPU en su rendimiento y los límites de E/S de un programa Python típico o cualquier programa de computadora. Los programas vinculados a la CPU generalmente llevan la CPU al límite. Estos programas se utilizan generalmente para cálculos matemáticos como multiplicaciones de matrices, búsqueda, procesamiento de imágenes, etc.

Los programas vinculados a E/S son aquellos programas que dedican tiempo a obtener entradas/salidas que pueden ser generadas por el usuario, archivo, base de datos, red, etc. Dichos programas tienen que esperar una cantidad significativa de tiempo hasta que la fuente proporcione la entrada. Por otro lado, la fuente también tiene su propio tiempo de procesamiento. Por ejemplo, un usuario está pensando en qué ingresar como entrada.

Entendamos el siguiente ejemplo.

Ejemplo -

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 start_time = time.time() countdown(COUNT) end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Producción:

 Time taken in seconds - 7.422671556472778 

Ahora modificamos el código anterior ejecutando los dos hilos.

Ejemplo - 2:

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 thread1 = Thread(target=countdown, args=(COUNT//2,)) thread2 = Thread(target=countdown, args=(COUNT//2,)) start_time = time.time() thread1.start() thread2.start() thread1.join() thread2.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Producción:

 Time taken in seconds - 6.90830135345459 

Como podemos ver, ambos códigos tardaron el mismo tiempo en finalizar. GIL impidió que los subprocesos vinculados a la CPU se ejecutaran en paralelo en el segundo código.

tabla desc en mysql

¿Por qué no se ha eliminado todavía el GIL?

Muchos programadores tienen quejas al respecto, pero Python no puede aportar cambios tan significativos como la eliminación de GIL. Otra razón es que GIL no ha mejorado por ahora. Si cambia en Python 3, creará algunos problemas graves. En lugar de eliminar GIL, el concepto GIL puede mejorar. Según Guido van Rossom -

'Daría la bienvenida a un conjunto de parches en Py3k sólo si el rendimiento de un programa de un solo subproceso (y de un programa de múltiples subprocesos pero vinculado a E/S) no disminuye'.

También hay muchos métodos disponibles que resuelven el mismo problema resuelto por GIL, pero son difíciles de implementar.

Cómo lidiar con el GIL de Python

El uso del multiprocesamiento es la forma más adecuada de evitar que el programa se convierta en GIL. Python ofrece varios intérpretes para cada proceso a ejecutar, por lo que en ese escenario, se proporciona un único subproceso a cada proceso en multiprocesamiento. Entendamos el siguiente ejemplo.

Ejemplo -

ls comandos linux
 from multiprocessing import Pool import time COUNT = 50000000 def countdown(num): while num>0: num -= 1 if __name__ == '__main__': pool = Pool(processes=2) start_time = time.time() r1 = pool.apply_async(countdown, [COUNT//2]) r2 = pool.apply_async(countdown, [COUNT//2]) pool.close() pool.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Producción:

 Time taken in seconds - 3.3707828521728516 

Puede parecer que se aumenta el rendimiento decente, pero la gestión de procesos tiene sus propios gastos generales y varios procesos son más pesados ​​que varios subprocesos.

Conclusión

En este tutorial, hemos discutido el GIL y cómo podemos usarlo. Le da el control a un solo subproceso para que se ejecute en ese momento. Este tutorial también cubrió por qué GIL es importante para los programadores de Python.