Python Global Interpreter Lock (GIL) es un tipo de bloqueo de proceso que python utiliza cuando se trata de procesos. Generalmente, Python solo usa un hilo para ejecutar el conjunto de declaraciones escritas. Esto significa que en python solo se ejecutará un hilo a la vez. El rendimiento del proceso de subproceso único y el proceso de subprocesos múltiples será el mismo en python y esto se debe a GIL en python. No podemos lograr subprocesos múltiples en python porque tenemos un bloqueo de intérprete global que restringe los subprocesos y funciona como un solo subproceso.
¿Qué problema resolvió GIL para Python?
Python tiene algo que ningún otro lenguaje tiene, que es un contador de referencias. Con la ayuda del contador de referencias, podemos contar el número total de referencias que se realizan internamente en python para asignar un valor a un objeto de datos. Debido a este contador, podemos contar las referencias y cuando este conteo llegue a cero, la variable u objeto de datos se liberará automáticamente. Por ejemplo
# Python program showing # use of reference counter import sys geek_var = "Geek" print(sys.getrefcount(geek_var)) string_gfg = geek_var print(sys.getrefcount(string_gfg))
Producción:
4 5
Esta variable de contador de referencia debía protegerse, porque a veces dos subprocesos aumentan o disminuyen su valor simultáneamente al hacerlo, puede provocar una fuga de memoria, por lo que para proteger el subproceso agregamos bloqueos a todas las estructuras de datos que se comparten entre subprocesos, pero a veces agregando bloqueos existe un bloqueo múltiple que conduce a otro problema que es interbloqueo. Para evitar la fuga de memoria y el problema de interbloqueos, utilizamos un bloqueo único en el intérprete que es Global Interpreter Lock (GIL).
¿Por qué se eligió el GIL como solución?
Python admite el lenguaje C en el backend y todas las bibliotecas relacionadas que tiene Python están escritas principalmente en C y C++. Debido a GIL, Python proporciona una mejor manera de lidiar con la administración de memoria segura para subprocesos. Global Interpreter Lock es fácil de implementar en python, ya que solo necesita proporcionar un único bloqueo a un subproceso para su procesamiento en python. El GIL es simple de implementar y se agregó fácilmente a Python. Proporciona un aumento de rendimiento a los programas de subproceso único, ya que solo se necesita administrar un bloqueo.
Impacto en los programas Python de subprocesos múltiples:
Cuando un usuario escribe programas de Python o cualquier programa de computadora, existe una diferencia entre aquellos que están vinculados a la CPU en su rendimiento y aquellos que están vinculados a E/S. La CPU llevó el programa a sus límites al realizar muchas operaciones simultáneamente, mientras que el programa de E/S tuvo que pasar tiempo esperando Entrada/Salida. Por ejemplo
Código 1: programa vinculado a la CPU que realiza una cuenta regresiva simple
# Python program showing # CPU bound program import time from threading import Thread COUNT = 50000000 def countdown(n): while n>0: n -= 1 start = time.time() countdown(COUNT) end = time.time() print('Time taken in seconds -', end - start)
Producción:
Time taken in seconds - 2.5236213207244873
Código 2: dos subprocesos que se ejecutan en paralelo
# Python program showing # two threads running parallel import time from threading import Thread COUNT = 50000000 def countdown(n): while n>0: n -= 1 t1 = Thread(target = countdown, args =(COUNT//2, )) t2 = Thread(target = countdown, args =(COUNT//2, )) start = time.time() t1.start() t2.start() t1.join() t2.join() end = time.time() print('Time taken in seconds -', end - start)
Producción:
Time taken in seconds - 2.183610439300537
Como puede ver, en el código anterior, dos códigos donde el proceso vinculado a la CPU y el proceso de subprocesos múltiples tienen el mismo rendimiento porque en el programa vinculado a la CPU porque GIL restringe la CPU para que solo funcione con un único subproceso. El impacto del subproceso vinculado a la CPU y los subprocesos múltiples será el mismo en python.
¿Por qué no se ha eliminado el GIL todavía?
GIL no se ha mejorado a partir de ahora porque python 2 tiene una implementación de GIL y si cambiamos esto en python 3, entonces nos creará un problema. Entonces, en lugar de eliminar GIL, mejoramos el concepto de GIL. Es una de las razones para no eliminar GIL todavía porque Python depende en gran medida de C en el backend y la extensión C depende en gran medida de los métodos de implementación de GIL. Aunque existen muchos más métodos para resolver los problemas que GIL resuelve, la mayoría de ellos son difíciles de implementar y pueden ralentizar el sistema.
Cómo lidiar con GIL de Python:
La mayoría de las veces usamos el multiprocesamiento para evitar que el programa GIL. En esta implementación, python proporciona un intérprete diferente para cada proceso a ejecutar, por lo que en este caso se proporciona un hilo único a cada proceso en multiprocesamiento.
# Python program showing # multiprocessing import multiprocessing import time COUNT = 50000000 def countdown(n): while n>0: n -= 1 if __name__ == "__main__": # creating processes start = time.time() p1 = multiprocessing.Process(target = countdown, args =(COUNT//2, )) p2 = multiprocessing.Process(target = countdown, args =(COUNT//2, )) # starting process 1 p1.start() # starting process 2 p2.start() # wait until process 1 is finished p1.join() # wait until process 2 is finished p2.join() end = time.time() print('Time taken in seconds -', end - start)
Producción:
Time taken in seconds - 2.5148496627807617
Como puede ver, no hay diferencia entre el tiempo que tarda el sistema de subprocesos múltiples y el sistema de procesamiento múltiple. Esto se debe a que un sistema de procesamiento múltiple tiene sus propios problemas que resolver. Entonces, esto no resolverá el problema, pero sí proporciona la solución que GIL permite que python realice.
Publicación traducida automáticamente
Artículo escrito por Jitender_1998 y traducido por Barcelona Geeks. The original can be accessed here. Licence: CCBY-SA