Esistono diverse implementazioni di Python, ad esempio CPython, IronPython, RPython, ecc.
Alcuni hanno un GIL, altri no. Ad esempio, CPython ha il GIL:
Da http://en.wikipedia.org/wiki/Global_Interpreter_Lock
Le applicazioni scritte in linguaggi di programmazione con un GIL possono essere progettate per utilizzare processi separati per ottenere il pieno parallelismo, poiché ogni processo ha il suo interprete e a sua volta ha il suo GIL.
Vantaggi del GIL
- Maggiore velocità dei programmi a thread singolo.
- Facile integrazione di librerie C che di solito non sono thread-safe.
Perché Python (CPython e altri) usa GIL
In CPython, il blocco dell'interprete globale, o GIL, è un mutex che impedisce a più thread nativi di eseguire contemporaneamente bytecode Python. Questo blocco è necessario principalmente perché la gestione della memoria di CPython non è thread-safe.
Il GIL è controverso perché impedisce ai programmi CPython multithread di sfruttare appieno i sistemi multiprocessore in determinate situazioni. Si noti che operazioni potenzialmente bloccanti o di lunga durata, come I / O, elaborazione delle immagini e crunching dei numeri NumPy, avvengono al di fuori di GIL. Pertanto, è solo nei programmi multithread che trascorrono molto tempo all'interno del GIL, interpretando il bytecode CPython, che il GIL diventa un collo di bottiglia.
Python ha un GIL rispetto al blocco a grana fine per diversi motivi:
È più veloce nel caso a thread singolo.
È più veloce nel caso multi-thread per i programmi i / o associati.
È più veloce nel caso multi-thread per i programmi cpu associati che svolgono il loro intenso lavoro di calcolo nelle librerie C.
Semplifica la scrittura delle estensioni C: non ci sarà alcun cambio di thread Python se non nel caso in cui lo consenti (ad esempio tra le macro Py_BEGIN_ALLOW_THREADS e Py_END_ALLOW_THREADS).
Rende più semplice il wrapping delle librerie C. Non devi preoccuparti della sicurezza del thread. Se la libreria non è thread-safe, tieni semplicemente bloccato GIL mentre lo chiami.
Il GIL può essere rilasciato da estensioni C. La libreria standard di Python rilascia GIL attorno a ogni chiamata di I / O bloccante. Pertanto, il GIL non ha conseguenze per le prestazioni dei server associati i / o. Puoi quindi creare server di rete in Python usando processi (fork), thread o I / O asincroni e GIL non ti ostacolerà.
Le librerie numeriche in C o Fortran possono essere chiamate allo stesso modo con il rilascio di GIL. Mentre l'estensione C è in attesa del completamento di una FFT, l'interprete eseguirà altri thread Python. In questo caso, un GIL è quindi più facile e veloce del bloccaggio a grana fine. Ciò costituisce la maggior parte del lavoro numerico. L'estensione NumPy rilascia GIL quando possibile.
I thread di solito sono un cattivo modo di scrivere la maggior parte dei programmi server. Se il carico è basso, il fork è più semplice. Se il carico è elevato, è meglio l'I / O asincrono e la programmazione guidata dagli eventi (ad es. Utilizzando il framework Twisted di Python). L'unica scusa per l'utilizzo dei thread è la mancanza di os.fork su Windows.
Il GIL è un problema se, e solo se, stai facendo un lavoro ad alta intensità di CPU in Python puro. Qui puoi ottenere un design più pulito usando i processi e il passaggio dei messaggi (ad esempio mpi4py). Esiste anche un modulo di "elaborazione" nel negozio di formaggi Python, che fornisce ai processi la stessa interfaccia dei thread (ovvero sostituisce il threading. Filettato con processing.Process).
I thread possono essere utilizzati per mantenere la reattività di una GUI indipendentemente dal GIL. Se il GIL compromette le tue prestazioni (vedi la discussione sopra), puoi lasciare che il tuo thread generi un processo e attendere che finisca.