versiones guia español descargar actualizar python multithreading scripting locking bytecode

python - guia - ¿Por qué el bloqueo de intérprete global?



qgis manual (6)

Con respecto a su segunda pregunta, no todos los lenguajes de scripts usan esto, pero solo los hace menos poderosos. Por ejemplo, los hilos en Ruby son green y no nativos.

En Python, los hilos son nativos y el GIL solo evita que se ejecuten en diferentes núcleos.

En Perl, los hilos son aún peores. Simplemente copian todo el intérprete y están lejos de ser tan utilizables como en Python.

¿Cuál es exactamente la función del bloqueo de intérprete global de Python? ¿Otros idiomas que se compilan en bytecode emplean un mecanismo similar?


El bloqueo de intérprete global es un gran bloqueo de tipo mutex que protege los contadores de referencia de las mangueras. Si está escribiendo código python puro, todo esto ocurre detrás de las escenas, pero si incrusta Python en C, entonces puede que tenga que tomar / liberar el bloqueo explícitamente.

Este mecanismo no está relacionado con la compilación de Python a bytecode. No es necesario para Java. De hecho, ni siquiera es necesario para Jython (python compilado a jvm).

ver también esta pregunta


En general, para cualquier problema de seguridad de hilos, necesitará proteger sus estructuras internas de datos con bloqueos. Esto se puede hacer con varios niveles de granularidad.

  • Puede usar el bloqueo de grano fino, donde cada estructura separada tiene su propio bloqueo.

  • Puede usar el bloqueo de grano grueso donde un bloqueo lo protege todo (el enfoque GIL).

Hay varios pros y contras de cada método. El bloqueo de grano fino permite un mayor paralelismo: dos hilos se pueden ejecutar en paralelo cuando no comparten ningún recurso. Sin embargo, hay una sobrecarga administrativa mucho más grande. Para cada línea de código, es posible que deba adquirir y liberar varios bloqueos.

El enfoque de grano grueso es el opuesto. Dos hilos no se pueden ejecutar al mismo tiempo, pero un hilo individual se ejecutará más rápido porque no está haciendo tanta contabilidad. En definitiva, se trata de una compensación entre la velocidad de un solo subproceso y el paralelismo.

Hubo algunos intentos de eliminar el GIL en python, pero la sobrecarga adicional para máquinas de un solo hilo era generalmente demasiado grande. Algunos casos en realidad pueden ser más lentos incluso en máquinas multiprocesador debido a la contención del bloqueo.

¿Otros idiomas que se compilan en bytecode emplean un mecanismo similar?

Varía, y probablemente no debería considerarse una propiedad de lenguaje sino una propiedad de implementación. Por ejemplo, hay implementaciones de Python como Jython e IronPython que utilizan el enfoque de subprocesamiento de su VM subyacente, en lugar de un enfoque GIL. Además, la próxima versión de Ruby parece estar avanzando towards introducción de un GIL.


Lo siguiente es del manual oficial de referencia de Python / C API :

El intérprete de Python no es totalmente seguro para subprocesos. Para admitir programas de Python de subprocesos múltiples, el hilo actual debe mantener un bloqueo global antes de que pueda acceder de forma segura a los objetos de Python. Sin el bloqueo, incluso las operaciones más simples podrían causar problemas en un programa de subprocesos múltiples: por ejemplo, cuando dos subprocesos incrementan simultáneamente el recuento de referencias del mismo objeto, el recuento de referencias podría incrementarse solo una vez en lugar de dos.

Por lo tanto, existe la regla de que solo el hilo que ha adquirido el bloqueo de intérprete global puede operar en objetos de Python o llamar a las funciones de Python / C API. Para admitir programas Python de subprocesos múltiples, el intérprete regularmente libera y vuelve a adquirir el bloqueo, por defecto, cada 100 instrucciones de bytecode (esto se puede cambiar con sys.setcheckinterval ()). El bloqueo también se libera y se vuelve a adquirir en operaciones de E / S potencialmente potenciales, como leer o escribir un archivo, para que se puedan ejecutar otros subprocesos mientras el subproceso que solicita la E / S espera que se complete la operación de E / S.

Creo que resume bastante bien el problema.


Python, como Perl 5, no fue diseñado desde cero para ser seguro para subprocesos. Los hilos fueron injertados después del hecho, por lo que el bloqueo del intérprete global se usa para mantener la exclusión mutua cuando solo un hilo está ejecutando código en un momento dado en las entrañas del intérprete.

Los hilos individuales de Python son cooperativamente multitarea por el propio intérprete haciendo ciclismo en el candado de vez en cuando.

Es necesario agarrar el candado usted mismo cuando habla con Python desde C cuando otros hilos de Python están activos para ''aceptar'' este protocolo y asegurarse de que no ocurra nada inseguro a sus espaldas.

Otros sistemas que tienen un patrimonio de subproceso único que más tarde se convirtió en sistemas multiproceso a menudo tienen algún mecanismo de este tipo. Por ejemplo, el kernel de Linux tiene el "Gran bloqueo de kernel" desde sus primeros días de SMP. Poco a poco, a medida que el rendimiento de subprocesos múltiples se convierte en un problema, hay una tendencia a tratar de romper este tipo de bloqueos en partes más pequeñas o reemplazarlos con algoritmos de bloqueo y estructuras de datos donde sea posible para maximizar el rendimiento.


Tal vez this artículo de la BDFL ayude.