¿Por qué no hay GIL en la máquina virtual de Java? ¿Por qué Python necesita tanto uno?

5 minutos de lectura

Espero que alguien pueda proporcionar una idea de lo que es fundamentalmente diferente acerca de la máquina virtual de Java que le permite implementar subprocesos sin la necesidad de un bloqueo de intérprete global (GIL), mientras que Python necesita tal maldad.

Python (el lenguaje) no necesita un GIL (por lo que se puede implementar perfectamente en JVM [Jython] y .NET [IronPython], y aquellas implementaciones multiproceso libremente). CPython (la implementación popular) siempre ha usado un GIL para facilitar la codificación (especialmente la codificación de los mecanismos de recolección de basura) y la integración de bibliotecas codificadas en C que no son seguras para subprocesos (solía haber un montón de esas alrededor; -).

los Golondrina descargada proyecto, entre otros objetivos ambiciosos, no plan una máquina virtual sin GIL para Python, para citar ese sitio, “Además, tenemos la intención de eliminar el GIL y corregir el estado de subprocesos múltiples en Python. Creemos que esto es posible mediante la implementación de un sistema GC más sofisticado, algo como Recycler de IBM (Bacon et al, 2001).”

  • Alex, ¿qué pasa con los viejos intentos de eliminar el GIL? ¿No hubo una tonelada de gastos generales con eso (un factor de 2 es lo que recuerdo)?

    – Bartosz Radaczyński

    15 de julio de 2009 a las 13:57

  • Sí, Bartosz, Greg Stein midió eso en 1999. La recolección de basura por conteo de referencia fue el asesino, forzando una enorme sobrecarga de bloqueo de grano fino. Es por eso que un GC más avanzado es crucial allí.

    – Alex Martelli

    15 de julio de 2009 a las 16:19

  • El equipo de Unladen Swallow ha renunciado a eliminar el GIL: code.google.com/p/unladen-swallow/wiki/…

    – Seun Osewa

    20 de marzo de 2010 a las 20:25

  • Las alternativas a Unladen y CPython son PyPy, Jython y IronPython. Los dos últimos no tienen un GIL, pero el uso del módulo de multiprocesamiento evita el GIL y es más seguro de todos modos.

    – Cees Timmermann

    12 de marzo de 2012 a las 11:30

avatar de usuario
greg bowyer

La JVM (al menos el punto de acceso) tiene un concepto similar al “GIL”, es mucho más fino en su granularidad de bloqueo, la mayor parte proviene de los GC en el punto de acceso que son más avanzados.

En CPython es un gran bloqueo (probablemente no sea tan cierto, pero lo suficientemente bueno por el bien de los argumentos), en JVM está más disperso con diferentes conceptos dependiendo de dónde se use.

Eche un vistazo, por ejemplo, a vm/runtime/safepoint.hpp en el código del punto de acceso, que es efectivamente una barrera. Una vez en un punto seguro, toda la VM se detiene con respecto al código Java, al igual que la VM de Python se detiene en GIL.

En el mundo de Java, estos eventos de pausa de VM se conocen como “detener el mundo”, en estos puntos solo el código nativo que está vinculado a ciertos criterios se ejecuta libremente, el resto de la VM se ha detenido.

Además, la falta de un bloqueo grueso en Java hace que JNI sea mucho más difícil de escribir, ya que JVM ofrece menos garantías sobre su entorno para llamadas FFI, una de las cosas que cpython hace bastante fácil (aunque no tan fácil como usar ctypes).

Hay un comentario abajo en esta publicación de blog. http://www.grouplens.org/node/244 eso sugiere la razón por la cual fue tan fácil prescindir de un GIL para IronPython o Jython, es que CPython usa el conteo de referencias mientras que las otras 2 VM tienen recolectores de basura.

No entiendo la mecánica exacta de por qué esto es así, pero parece una razón plausible.

  • Cuando comparte objetos de manera promiscua entre subprocesos, trabajar cuando nadie tiene una referencia a un objeto en particular es moderadamente incómodo. El conteo de referencias con un bloqueo global es una forma (costosa). Una forma diferente de resolverlo habría sido dejar que un subproceso a la vez mantuviera referencias al objeto, lo que haría que la mayor parte de la actividad fuera local del subproceso a costa de hacer que las comunicaciones entre subprocesos fueran más incómodas. Personalmente, creo que es revelador que HPC use el paso de mensajes entre procesadores y no memoria compartida, y que lo haga por razones de escalabilidad…

    – Becarios Donal

    12 de abril de 2010 a las 22:03

  • Hm, bueno, básicamente, hay 2 tipos de recolección de basura: marcar y barrer (o detener y cioy, o como se llame su implementación particular de este enfoque) y recuento de ref. La JVM actualmente usa una combinación de ambos en mi humilde opinión (recolección de basura generacional). Por lo tanto, ¿Java debería sufrir los mismos problemas con la sincronización de contadores de referencia que Python?

    – Miguel Cerveza

    29 de abril de 2021 a las 18:57


En esto Enlace tienen la siguiente explicación:

… “Partes del Intérprete no son seguras para subprocesos, aunque principalmente porque hacer que todas sean seguras para subprocesos mediante el uso masivo de bloqueos ralentizaría extremadamente el subproceso único (fuente). Esto parece estar relacionado con el recolector de basura CPython que usa el conteo de referencias (JVM y CLR no lo hacen y, por lo tanto, no necesitan bloquear/liberar un conteo de referencias cada vez). Pero incluso si alguien pensara en una solución aceptable y la implementara, las bibliotecas de terceros seguirían teniendo los mismos problemas”.

Python carece de jit/aot y el marco de tiempo en el que se escribió en procesadores multiproceso no existía. Alternativamente, puede volver a compilar todo en Julia lang que carece de GIL y obtener un aumento de velocidad en su código Python. También Jython apesta, es más lento que Cpython y Java. Si desea apegarse a Python, considere usar complementos paralelos, no obtendrá un aumento de velocidad instantáneo, pero puede hacer programación paralela con el complemento correcto.

  • ¿Qué pasa con PyPy?

    – denis631

    22 de enero de 2019 a las 12:30

  • ¿Qué pasa con PyPy?

    – denis631

    22 de enero de 2019 a las 12:30

¿Ha sido útil esta solución?