Perché non c'è GIL nella Java Virtual Machine? Perché Python ne ha bisogno così tanto?


177

Spero che qualcuno possa fornire alcune informazioni su ciò che è fondamentalmente diverso nella Java Virtual Machine che gli consente di implementare correttamente i thread senza la necessità di un Global Interpreter Lock (GIL), mentre Python richiede un tale male.

Risposte:


223

Python (il linguaggio) non ha bisogno di un GIL (motivo per cui può essere perfettamente implementato su JVM [Jython] e .NET [IronPython], e quelle implementazioni multithread liberamente). CPython (l'implementazione popolare) ha sempre usato un GIL per facilitare la codifica (in particolare la codifica dei meccanismi di garbage collection) e l'integrazione di librerie con codice C non thread-safe (c'erano un sacco di quelli in giro; -).

Il progetto Unladen Swallow , tra gli altri obiettivi ambiziosi, pianifica una macchina virtuale senza GIL per Python - per citare quel sito, "Inoltre, intendiamo rimuovere il GIL e correggere lo stato del multithreading in Python. Crediamo che sia possibile attraverso l'implementazione di un sistema GC più sofisticato, qualcosa come IBM Recycler (Bacon et al, 2001). "


6
Alex, che dire dei vecchi tentativi di rimuovere il GIL, non c'era un sacco di sovraccarico in questo (un fattore 2 è quello che ricordo)?
Bartosz Radaczyński,

10
Sì, Bartosz, Greg Stein lo ha misurato nel 1999. La raccolta dei rifiuti secondo il conteggio dei riferimenti era l'assassino, costringendo un enorme sovraccarico di chiusura a grana fine. Ecco perché un GC più avanzato è fondamentale lì.
Alex Martelli,

80
Il team di Unladen Swallow ha rinunciato alla rimozione di GIL: code.google.com/p/unladen-swallow/wiki/…
Seun Osewa

1
Le alternative a Unladen e CPython sono PyPy, Jython e IronPython. Gli ultimi due non hanno un GIL, ma l'uso del modulo multiprocessore elimina il GIL ed è comunque più sicuro.
Cees Timmerman,

50

Il JVM (almeno hotspot) ha un concetto simile al "GIL", è solo molto più fine nella sua granularità di blocco, la maggior parte di questo deriva dai GC nell'hotspot che sono più avanzati.

In CPython è un grande blocco (probabilmente non è così vero, ma abbastanza buono per amor di argomenti), nella JVM è più diffuso con concetti diversi a seconda di dove viene utilizzato.

Dai un'occhiata, ad esempio, a vm / runtime / safepoint.hpp nel codice hotspot, che è effettivamente una barriera. Una volta in un punto di sicurezza, l'intera VM si è arrestata per quanto riguarda il codice java, proprio come la VM di Python si ferma al GIL.

Nel mondo Java tali eventi di pausa della VM sono noti come "stop-the-world", in questi punti solo il codice nativo associato a determinati criteri è in esecuzione libera, il resto della VM è stato arrestato.

Inoltre la mancanza di un blocco grossolano in Java rende JNI molto più difficile da scrivere, poiché la JVM offre meno garanzie sul suo ambiente per le chiamate FFI, una delle cose che cpython rende abbastanza facile (anche se non facile come l'uso di ctypes).


7

C'è un commento in basso in questo post del blog http://www.grouplens.org/node/244 che suggerisce il motivo per cui è stato così facile rinunciare a un GIL per IronPython o Jython, è che CPython utilizza il conteggio dei riferimenti mentre le altre 2 macchine virtuali hanno i garbage collector.

La meccanica esatta del perché questo è così non capisco, ma sembra una ragione plausibile.


5
Quando condividi in modo promiscuo oggetti tra thread, capire se nessuno ha più un riferimento a un oggetto particolare è moderatamente imbarazzante. Il conteggio dei riferimenti con un blocco globale è un modo (costoso). Un modo diverso di risolverlo sarebbe stato quello di lasciare che un thread alla volta trattenesse i riferimenti all'oggetto, il che renderebbe la maggior parte delle attività locali thread al costo di rendere più scomode le comunicazioni tra thread. Personalmente, penso che stia dicendo che HPC utilizza il passaggio di messaggi tra processori e non memoria condivisa e che lo fa per motivi di scalabilità ...
Donal Fellows

0

In questo link hanno la seguente spiegazione:

... "Parti dell'interprete non sono thread-safe, anche se principalmente perché renderle tutte thread-safe con un uso massiccio del blocco rallenterebbe estremamente il single-thread ( sorgente ). Questo sembra essere correlato al garbage collector di CPython usando il conteggio dei riferimenti (JVM e CLR no, e quindi non è necessario bloccare / rilasciare ogni volta un conteggio dei riferimenti). Ma anche se qualcuno pensasse a una soluzione accettabile e la implementasse, le librerie di terze parti avrebbero comunque gli stessi problemi. "


-1

Python manca di jit / aot e il periodo di tempo in cui è stato scritto su processori multithread non esisteva. In alternativa, puoi ricompilare tutto in Julia lang che manca di GIL e ottenere un aumento di velocità sul tuo codice Python. Anche Jython fa schifo è più lento di Cpython e Java. Se si desidera attenersi a Python, considerare l'utilizzo di plugin paralleli, non si otterrà un aumento di velocità istantaneo ma è possibile eseguire la programmazione parallela con il plugin giusto.


che dire di PyPy?
denis631,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.