Nota: donde sea que mencione thread
me refiero específicamente a hilos en Python hasta que se indique explícitamente.
Los subprocesos funcionan de manera un poco diferente en Python si proviene de un C/C++
segundo plano. En Python, solo un subproceso puede estar en estado de ejecución en un momento dado, lo que significa que los subprocesos en Python no pueden aprovechar realmente el poder de varios núcleos de procesamiento, ya que, por diseño, no es posible que los subprocesos se ejecuten en paralelo en varios núcleos.
Como la administración de memoria en Python no es segura para subprocesos, cada subproceso requiere un acceso exclusivo a las estructuras de datos en el intérprete de Python. Este acceso exclusivo se adquiere mediante un mecanismo llamado (bloqueo de interpretación global) .GIL
Why does python use GIL?
Para evitar que varios subprocesos accedan al estado del intérprete simultáneamente y corrompan el estado del intérprete.
La idea es que cada vez que se está ejecutando un hilo (incluso si es el hilo principal) , se adquiere un GIL y, después de un intervalo de tiempo predefinido, el hilo actual libera el GIL y otro hilo lo vuelve a adquirir (si lo hay).
Why not simply remove GIL?
No es que sea imposible eliminar GIL, es solo que, en el intento de hacerlo, terminamos colocando múltiples bloqueos dentro del intérprete para serializar el acceso, lo que hace que incluso una aplicación de un solo subproceso tenga menos rendimiento.
por lo que el costo de eliminar GIL se compensa con un rendimiento reducido de una aplicación de un solo hilo, lo que nunca se desea.
So when does thread switching occurs in python?
El cambio de hilo ocurre cuando se libera GIL, entonces, ¿cuándo se libera GIL? Hay dos escenarios a tener en cuenta.
Si un subproceso está realizando operaciones vinculadas a la CPU (procesamiento de imágenes Ex).
En las versiones anteriores de Python, el cambio de subproceso solía ocurrir después de un número fijo de instrucciones de Python. Estaba configurado de forma predeterminada en 100
. Resultó que no es una política muy buena para decidir cuándo debe ocurrir el cambio, ya que el tiempo dedicado a ejecutar una sola instrucción puede variar de milisegundos a incluso un segundo. Por lo tanto, liberar GIL después de cada 100
instrucción, independientemente del tiempo que tarden en ejecutarse, es una política deficiente.
En las nuevas versiones, en lugar de utilizar el recuento de instrucciones como métrica para cambiar de hilo, se utiliza un intervalo de tiempo configurable. El intervalo de cambio predeterminado es de 5 milisegundos. Puede obtener el intervalo de cambio actual utilizando sys.getswitchinterval()
. Esto se puede modificar usandosys.setswitchinterval()
Si un subproceso está realizando algunas operaciones IO enlazadas (acceso al sistema de archivos Ex o
IO de red)
GIL se libera siempre que el hilo está esperando que se complete la operación de E / S.
Which thread to switch to next?
El intérprete no tiene su propio programador. Qué hilo se programa al final del intervalo es decisión del sistema operativo. .