logo

Kaj je GIL v Pythonu? Globalna ključavnica tolmača

Ta vadnica bo osredotočena na eno od pomembnih tem Pythona, GIL. Pokrili bomo tudi, kako GIL vpliva na delovanje programov Python z implementacijo kode. Preden se potopimo v to temo, si oglejmo osnovno predstavo o GIL.

GIL ali Global Interpreter Lock

Python Global Interpreter Lock ali GIL je pomemben del večnitnega programiranja. To je vrsta zaklepanja procesa, ki se uporablja pri delu z več procesi. Omogoča nadzor samo eni niti. Na splošno Python uporablja eno nit za izvajanje enega samega procesa. Z GIL dobimo enak rezultat zmogljivosti enonitnih in večnitnih procesov. Omejuje doseganje večnitnosti v Pythonu, ker preprečuje niti in deluje kot ena nit.

Opomba – Python ne podpira večnitnosti, ker nam paketi niti niso mogli dovoliti uporabe več jeder CPU.

Zakaj Python Developers uporablja GIL?

Python ponuja edinstveno funkcijo števca referenc, ki se uporablja za upravljanje pomnilnika. Števec sklicev šteje skupno število internih sklicev v Pythonu za dodelitev vrednosti podatkovnemu objektu. Ko štetje sklicev doseže nič, se dodeljeni pomnilnik objekta sprosti. Oglejmo si spodnji primer.

Primer -

seznam java
 import sys a = [] b = a sys.getrefcount(a) 

Glavna skrb v zvezi s spremenljivko števila referenc je, da lahko nanjo vpliva, ko dve ali tri niti poskušajo povečati ali zmanjšati njeno vrednost hkrati. Znano je kot stanje dirke. Če pride do tega stanja, lahko povzroči uhajanje pomnilnika, ki se nikoli ne sprosti. Lahko se zruši ali ima hrošče v programu Python.

GIL nam pomaga odstraniti takšno situacijo z uporabo ključavnic za vse podatkovne strukture v skupni rabi v nitih, tako da se ne spreminjajo nedosledno. Python ponuja enostaven način za implementacijo GIL, saj se ukvarja z upravljanjem pomnilnika, ki je varno za niti. GIL zahteva, da se za obdelavo v Pythonu ponudi eno samo zaklepanje niti. Poveča zmogljivost enonitnega programa, saj je treba obravnavati samo eno ključavnico. Pomaga tudi pri izdelavi katerega koli programa, vezanega na CPE, in preprečuje stanje zastojev.

int v niz java

Vpliv na večnitne programe Python

Obstaja razlika med mejami procesorja v njihovi zmogljivosti in mejami V/I za tipičen program Python ali kateri koli računalniški program. Programi, ki so vezani na CPE, na splošno potisnejo CPE do njegovih meja. Ti programi se običajno uporabljajo za matematične izračune, kot so matrična množenja, searing, obdelava slik itd.

V/I vezani programi so tisti programi, ki porabijo čas za pridobitev vhoda/izhoda, ki ga lahko ustvari uporabnik, datoteka, baza podatkov, omrežje itd. Takšni programi morajo čakati precej časa, dokler vir ne zagotovi vhoda. Po drugi strani pa ima vir tudi svoj čas obdelave. Na primer - uporabnik razmišlja, kaj naj vnese kot vnos.

Razumejmo naslednji primer.

primer -

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 start_time = time.time() countdown(COUNT) end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Izhod:

 Time taken in seconds - 7.422671556472778 

Zdaj spremenimo zgornjo kodo z izvajanjem dveh niti.

Primer - 2:

 import time from threading import Thread COUNT = 100000000 def countdown(num): while num>0: num -= 1 thread1 = Thread(target=countdown, args=(COUNT//2,)) thread2 = Thread(target=countdown, args=(COUNT//2,)) start_time = time.time() thread1.start() thread2.start() thread1.join() thread2.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Izhod:

 Time taken in seconds - 6.90830135345459 

Kot lahko vidimo, sta obe kodi potrebovali enak čas za dokončanje. GIL je v drugi kodi preprečil vzporedno izvajanje niti, vezanih na CPE.

niz za klepet

Zakaj GIL še ni bil odstranjen?

Mnogi programerji se pritožujejo glede tega, vendar Python ne more prinesti sprememb tako pomembnih kot odstranitev GIL. Drugi razlog je, da GIL še ni izboljšan. Če se spremeni v Python 3, bo to povzročilo nekaj resnih težav. Namesto odstranitve GIL se lahko koncept GIL izboljša. Po mnenju Guida van Rossoma -

'Pozdravil bi nabor popravkov v Py3k le, če se zmogljivost enonitnega programa (in večnitnega, vendar vezanega na V/I) ne zmanjša.'

Na voljo je tudi veliko metod, ki rešujejo isti problem, kot ga rešuje GIL, vendar jih je težko izvesti.

Kako ravnati s Pythonovim GIL

Uporaba večprocesiranja je najprimernejši način za preprečevanje GIL programa. Python ponuja različne tolmače za vsak proces, ki se izvaja, tako da je v tem scenariju za vsak proces v večprocesiranju zagotovljena ena nit. Razumejmo naslednji primer.

Primer -

drsenje z miško ne deluje
 from multiprocessing import Pool import time COUNT = 50000000 def countdown(num): while num>0: num -= 1 if __name__ == '__main__': pool = Pool(processes=2) start_time = time.time() r1 = pool.apply_async(countdown, [COUNT//2]) r2 = pool.apply_async(countdown, [COUNT//2]) pool.close() pool.join() end_time = time.time() print('Time taken in seconds -', end_time - start_time) 

Izhod:

 Time taken in seconds - 3.3707828521728516 

Morda se zdi spodobna zmogljivost povečana, vendar ima upravljanje procesov lastne stroške in več procesov je težjih od več niti.

Zaključek

V tej vadnici smo razpravljali o GIL in o tem, kako ga lahko uporabimo. Omogoča nadzor eni niti, ki se izvaja hkrati. Ta vadnica je prav tako pokrivala, zakaj je GIL pomemben za programerje Python.