Tämä opetusohjelma keskittyy yhteen tärkeimmistä Pythonin aiheista, GIL:stä. Käsittelemme myös kuinka GIL vaikuttaa Python-ohjelmien suorituskykyyn koodin toteutuksen kanssa. Ennen kuin sukeltaa tähän aiheeseen, saamme peruskäsityksen GIL:stä.
GIL tai Global Interpreter Lock
Python Global Interpreter Lock eli GIL on tärkeä osa monisäikeistä ohjelmointia. Se on eräänlainen prosessilukko, jota käytetään useiden prosessien kanssa työskennellessä. Se antaa hallinnan vain yhdelle säikeelle. Yleensä Python käyttää yhtä säiettä yhden prosessin suorittamiseen. Saamme saman suorituskykytuloksen yksisäikeisistä ja monisäikeisistä prosesseista käyttämällä GIL:ää. Se rajoittaa monisäikeisyyden saavuttamista Pythonissa, koska se estää säikeet ja toimii yhtenä säietenä.
Huomautus - Python ei tue monisäikeistystä, koska ketjutuspaketit eivät voineet antaa meidän käyttää useita prosessoriytimiä.
Miksi Python Developers käyttää GIL:ää?
Python tarjoaa ainutlaatuisen viitelaskurin ominaisuuden, jota käytetään muistin hallintaan. Viittauslaskuri laskee Pythonissa sisäisesti tehtyjen viittausten kokonaismäärän arvon määrittämiseksi tietoobjektille. Kun viitemäärät saavuttavat nollan, kohteen määrätty muisti vapautetaan. Katsotaanpa alla olevaa esimerkkiä.
Esimerkki -
merkkijono split bash
import sys a = [] b = a sys.getrefcount(a)
Viitemäärämuuttujan suurin huolenaihe on, että siihen voi vaikuttaa, kun kaksi tai kolme säiettä yrittää lisätä tai vähentää sen arvoa samanaikaisesti. Se tunnetaan kilpailutilanteena. Jos tämä tila ilmenee, se voi aiheuttaa muistivuodon, jota ei koskaan vapauteta. Se voi kaatua tai tehdä virheitä Python-ohjelmassa.
GIL auttaa meitä poistamaan tällaisen tilanteen käyttämällä kaikkien säikeiden jaettujen tietorakenteiden lukituksia, jotta niitä ei muuteta epäjohdonmukaisesti. Python tarjoaa helpon tavan toteuttaa GIL, koska se käsittelee säikeen turvallista muistinhallintaa. GIL edellyttää yhden lukituksen tarjoamista säikeelle käsittelyä varten Pythonissa. Se lisää yksisäikeisen ohjelman suorituskykyä, koska vain yksi lukko vaatii käsittelyn. Se auttaa myös tekemään prosessoriin sidottuja ohjelmia ja estää lukkiutuman.
int merkkijonoon java
Vaikutus monisäikeisiin Python-ohjelmiin
Suorituskyvyssä on ero CPU-rajojen ja tyypillisen Python-ohjelman tai minkä tahansa tietokoneohjelman I/O-rajoitusten välillä. Suorittimeen sidotut ohjelmat työnnetään yleensä suorittimen rajojaan. Näitä ohjelmia käytetään yleensä matemaattiseen laskemiseen, kuten matriisikertolaskuihin, leikkaamiseen, kuvankäsittelyyn jne.
I/O-sidotut ohjelmat ovat ohjelmia, jotka käyttävät aikaa saadakseen syötteen/tulosteen, jonka käyttäjä, tiedosto, tietokanta, verkko jne. voivat luoda. Tällaisten ohjelmien on odotettava jonkin verran aikaa, kunnes lähde tarjoaa syötteen. Toisaalta lähteellä on myös oma käsittelyaikansa. Esimerkiksi - käyttäjä miettii, mitä syöttää syötteeksi.
Ymmärretään seuraava esimerkki.
Esimerkki -
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)
Lähtö:
Time taken in seconds - 7.422671556472778
Nyt muokkaamme yllä olevaa koodia suorittamalla kaksi säiettä.
Esimerkki - 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)
Lähtö:
Time taken in seconds - 6.90830135345459
Kuten näemme, molempien koodien valmistuminen kesti saman ajan. GIL esti suorittimeen sidottuja säikeitä suorittamasta rinnakkain toisessa koodissa.
yksinkertainen java ohjelma
Miksi GIL:ää ei ole vielä poistettu?
Monet ohjelmoijat valittavat tästä, mutta Python ei voi tuoda muutoksia niin merkittäviin kuin GIL:n poistaminen. Toinen syy on se, että GIL:ää ei ole parannettu toistaiseksi. Jos se muuttuu Python 3:ssa, se aiheuttaa vakavia ongelmia. GIL:n poistamisen sijaan GIL-konsepti voi parantaa. Guido van Rossomin mukaan -
'Ottaisin mielelläni korjaustiedostoja Py3k:hen vain, jos yksisäikeisen ohjelman (ja monisäikeisen mutta I/O-sidottuohjelman) suorituskyky ei heikkene'.
Saatavilla on myös monia menetelmiä, jotka ratkaisevat saman GIL:n ratkaiseman ongelman, mutta niitä on vaikea toteuttaa.
Pythonin GIL:n käsittely
Monikäsittely on sopivin tapa estää ohjelmaa GIL:stä. Python tarjoaa erilaisia tulkkeja kullekin prosessille suoritettavaksi, joten siinä skenaariossa yksi säie tarjotaan jokaiselle monikäsittelyprosessille. Ymmärretään seuraava esimerkki.
Esimerkki -
palautustyyppi javassa
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)
Lähtö:
Time taken in seconds - 3.3707828521728516
Saattaa tuntua, että kunnollinen suorituskyky on lisääntynyt, mutta prosessien hallinnassa on omat yleiskustannukset ja useat prosessit ovat raskaampia kuin useat säikeet.
Johtopäätös
Tässä opetusohjelmassa olemme keskustelleet GIL:stä ja kuinka voimme käyttää sitä. Se antaa ohjauksen yksittäiselle säikeelle suoritettavaksi kerralla. Tämä opetusohjelma käsitteli myös, miksi GIL on tärkeä Python-ohjelmoijille.