Miért írták meg a Pythont a GIL-lel?

Úgy tűnik, hogy a globális tolmácszárat (GIL) gyakran emlegetik fő okként, amiért a threading és hasonlók a trükkös érintés a Pythonban – ami felveti a kérdést “Miért történt ez egyáltalán?”

Mivel nem vagyok programozó, fogalmam sincs, hogy miért lehet ez – mi volt a logika a GIL behelyezése mögött?

Megjegyzések

  • A Wikipedia cikk kimondja, hogy ” a GIL jelentős akadályt jelenthet a párhuzamosság előtt – ez az az ár, amelyet azért fizetnek, hogy a nyelv dinamikája ” , és folytatja, hogy ” Az ilyen zár alkalmazásának okai a következők: az egyszálú programok megnövekedett sebessége (nincs szükség különféle adatstruktúrák zárolásának megszerzésére vagy feloldására), valamint a C könyvtárak egyszerű integrálása, amelyek általában nem szálkamentes. ”
  • @RobertHarvey, a dinamizmusnak semmi köze ezzel. A probléma a mutáció.
  • stackoverflow.com/questions/265687/…
  • Nem segíthet ‘ abban, hogy úgy érezzük, hogy a Java ‘ hez hasonlóan az aláíratlan numerikus számok hiányában az volt a célja, hogy megakadályozzák azokat, akik nem ‘ nem tudják, mit csinálnak ‘, és lőnek maguknak. Sajnos, aki csinál tudja, mit csinál ‘, hiányos nyelvet kap, ami valódi szégyen, mert a Python nagyon sok más módon ringat
  • @Basic kell lennie valamilyen szabványos módszernek a bájt tömbök kezelésére a Java-ban (sokáig nem használtam ‘, hogy használjam) a kriptográfiai matematika elvégzéséhez. A Python (például) nem rendelkezik ‘ t aláíró számmal, de én ‘ nem is próbálnék bitenként műveleteket végezni vele, mert vannak jobb módszerek.

Válasz

A Python többféle megvalósítással rendelkezik, például CPython, IronPython, RPython, stb.

Néhányuknak van GIL-je, van, akinek “” nincs. Például a CPython-nak van GIL-je:

From http://en.wikipedia.org/wiki/Global_Interpreter_Lock

A GIL-sel programozási nyelveken írt alkalmazások úgy alakíthatók ki, hogy különálló folyamatokat használnak a teljes párhuzamosság elérése érdekében, mivel mindegyik folyamatnak megvan a maga értelmezője és viszont megvan a saját GIL-je.

A GIL előnyei

  • Az egyszálú programok megnövelt sebessége.
  • A C könyvtárak egyszerű integrálása, amelyek általában nem biztonságosak a szálak számára.

Miért használja a Python (CPython és mások) a GIL

A CPythonban a globális értelmezői zár vagy a GIL olyan mutex, amely megakadályozza, hogy több natív szál egyszerre futtassa a Python bytecode-okat. Erre a zárolásra elsősorban azért van szükség, mert a CPython memóriakezelése nem szálkamentes.

A GIL ellentmondásos, mert megakadályozza, hogy a többszálú CPython programok bizonyos helyzetekben teljes mértékben kihasználják a többprocesszoros rendszerek előnyeit. a régóta futó műveletek, mint például az I / O, a képfeldolgozás és a NumPy számgörgetés, a GIL-en kívül történnek. Ezért csak a többszálú programokban, amelyek sok időt töltenek a GIL belsejében, a CPython bytecode értelmezésével, válik a GIL szűk keresztmetszet.

A Pythonnak GIL-je van a finomszemcsés zárolással szemben, több okból is:

  • Egyszálas esetben gyorsabb.

  • Gyorsabb a többszálas esetben az i / o kötött programok esetében.

  • Gyorsabb a többszálas esetben a CPU-ra kötött programok esetében, amelyek nem számításigényes munkájuk a C könyvtárakban.

  • Ez teszi A C kiterjesztések könnyebben írhatók: nem lesz kapcsoló a Python szálakra, kivéve ott, ahol megengedi ennek megtörténését (azaz a Py_BEGIN_ALLOW_THREADS és a Py_END_ALLOW_THREADS makrók között).

  • Megkönnyíti a C könyvtárak csomagolását. Nem kell aggódnia a szálbiztonság miatt. Ha a könyvtár nem szálbiztonságos, akkor a GIL-t egyszerűen zárva kell tartania, amíg hívja.

A GIL képes A Python szabványos könyvtára minden blokkoló i / o hívás körül kiadja a GIL-t. Így a GIL-nek nincs következménye az i / o kötött szerverek teljesítményére. Így létrehozhat hálózati szervereket a Pythonban folyamatok (fork), szálak vagy aszinkron i / o használatával, és a GIL nem fogja akadályozni.

A C vagy a Fortran numerikus könyvtárai hasonlóan meghívhatók a GIL kiadva. Amíg a C kiterjesztése egy FFT befejezésére vár, az tolmács más Python szálakat hajt végre.A GIL tehát ebben az esetben is könnyebb és gyorsabb, mint a finom szemcsés rögzítés. Ez képezi a numerikus munka nagy részét. A NumPy kiterjesztés, amikor csak lehetséges, kiadja a GIL-t.

A szálak általában rossz módszerek a legtöbb szerverprogram megírásához. Ha a terhelés alacsony, a villázás könnyebb. Nagy terhelés esetén jobb az aszinkron i / o és az eseményvezérelt programozás (pl. A Python Twisted keretrendszerének használata). A szálak használatának egyetlen mentsége az os.fork hiánya a Windows rendszeren.

A GIL akkor és csak akkor jelent problémát, ha tiszta Python-ban végez CPU-intenzív munkát. Itt tisztább kialakítást kaphat a folyamatok és az üzenetátadás (pl. Mpi4py) használatával. Van egy “feldolgozó” modul is a Python sajtban shop, amely a folyamatoknak ugyanazt az interfészt adja, mint a szálak (azaz cserélje ki a threading.Thread-et a processing.Process-szal).

A szálak felhasználhatók a GUI reakciókészségének fenntartására a GIL-től függetlenül. Ha a GIL rontja a teljesítményét (vö. a fenti megbeszéléssel), hagyhatja, hogy a szál egy folyamatot előidézzen, és megvárja, amíg befejeződik.

Megjegyzések

  • Savanyú szőlőnek tűnik nekem. A Python ‘ nem tudja megfelelően elvégezni a szálakat, ezért megfogalmazza azokat az okokat, amelyek miatt a szálak szükségtelenek vagy rosszak. ” Ha a terhelés alacsony, fo Az rking könnyebb “, komolyan? És a GIL ” gyorsabb ” minden esetben, csak akkor, ha ragaszkodik a referenciaszámláló GC használatához.
  • s/RPython/PyPy/g. @MichaelBorgwardt Indokolás a pro GIL-nek a kérdés lényege, nem ‘ ez? Bár egyetértek azzal, hogy ennek a válasznak néhány tartalma (nevezetesen az alternatívák tárgyalása) a lényeg mellett áll. És jóban vagy rosszban is, az újraszámlálástól ma már szinte lehetetlen megszabadulni – ez mélyen be van építve az egész API- és kódbázisba; ‘ szinte lehetetlen megszabadulni tőle anélkül, hogy átírnánk a kód felét és nem tönkretennénk az összes külső kódot.
  • Don ‘ ne felejtsd el a multiprocessing könyvtárat – a szabványt a 2.6 óta. A ‘ munkakészletek rendkívül simulékony elvonások a párhuzamosság néhány egyszerű típusához.
  • @alcalde Csak akkor, ha nem ‘ nem tudom, mit csinálsz ‘ és / vagy nem akarod ‘ nem akarod, hogy szálaid együttműködhessenek / kommunikálni. Ellenkező esetben ez ‘ királyi fájdalmat okoz a hátuljában, különös tekintettel arra, hogy néhány operációs rendszeren új folyamat indul. Van 32 magos kiszolgálónk, ezért a CPython teljes kihasználásához ‘ d 32 folyamatra van szükségem. Ez ‘ nem egy ” jó megoldás ” it ‘ sa hack a CPython ‘ hiányosságainak kiküszöbölésére.
  • Annak a ténynek, hogy a szálak nem a Windows platformon léteznek, elég bizonyítéknak kell lennie arra, hogy a villa nem ‘ nem megfelelő minden helyzetben.

Válasz

Először off: A Pythonnak nincs GIL-je. A Python egy programozási nyelv. A programozási nyelv absztrakt matematikai szabályok és korlátozások összessége. A Python nyelvspecifikációjában semmi nem mondja ki, hogy GIL-nek kell lennie.

A Pythonnak sokféle megvalósítása létezik. Van, akinek van GIL-je, van, akinek nem.

A GIL használatának egyik egyszerű magyarázata, hogy a párhuzamos kód megírása nehéz. Ha óriási zárat helyez a kódja köré, arra kényszeríti, hogy mindig sorozatban fusson. Megoldva a problémát!

Különösen a CPythonban az egyik fontos cél az, hogy megkönnyítsük a tolmács kiterjesztését C-be írt bővítményekkel. Ismét nehéz egyidejű kódot írni, tehát garantálva, hogy nem lesz egyidejűség, megkönnyíti a tolmács kiterjesztések írását. Ráadásul sok ilyen kiterjesztés csak vékony burkoló a meglévő könyvtárak köré, amelyeket esetleg nem az egyidejűség szem előtt tartásával írtak.

Megjegyzések

  • Ez ‘ ugyanaz az érv, mint a Java ‘ esetében, ha nincsenek aláíratlan numerikus típusok – a fejlesztők szerint mindenki más ostobább, mint ők …
  • @Basic – hidd el vagy sem, még akkor is, ha ‘ nem vagy igazán, de tényleg hülye, kiderül, hogy olyan nyelv birtoklása, amely egyszerűsítő feltételezéseket tesz, amelyek azt jelentik, hogy nem ‘ nem gondolhat bizonyos dolgokra annak érdekében, hogy működőképesek legyenek, még mindig hasznos dolog.A CPython kiválóan alkalmas bizonyos dolgokra, beleértve az egyszerű, többszálú alkalmazásokat is (ahol a program IO-val kötött, ami sokan vannak, és ezért a GIL nem számít ‘), mert a tervezési döntések a GIL a legjobb megoldás megkönnyíti ezen alkalmazások programozását is, különös tekintettel arra, hogy támogatja az atomi műveleteket a gyűjteményeken .
  • @Jules Igen, ez ‘ nagyon praktikus, egészen addig, amíg nincs szüksége ezekre a képességekre. cpython ‘ s ” előnyben részesített ” ” csak írd be egy másik nyelvre, például c ++ “, és ez azt jelenti, hogy elveszíted minden egyes python előnyét. Ha ‘ a kód felét a c ++ nyelven írja, akkor miért indulna a Python? Bizony, kis API / ragasztó projekteknél ‘ gyorsan és egyszerűen, az ETL esetében pedig ‘ senki sincs, de ‘ s semmire sem alkalmas, amely nehéz emelést igényel. Ugyanaz, mint a Java használata a hardverrel való beszélgetéshez … ‘ majdnem komikus a karika, amin át kell ugranod.
  • @Basic A Python egyik ‘ s és így a CPython ‘ alapvető filozófiáinak kiterjesztése az, hogy a technológiát ” barátságossá és könnyen használható “. A globális zár nélküli párhuzamos programozás nem az. Figyelembe véve, hogy sok megvalósítás létezik GIL nélkül, van értelme legalább egy olyan megvalósítást biztosítani, amely rendelkezik vele.
  • Azt mondod, hogy ” van értelme legalább megadni egy megvalósítás, amellyel rendelkezik. ” tetszik ‘ ez a nyilvánvaló következtetés, de nincs más nyelv I ‘ m tudatában van annak, hogy ilyen módon csalja a fejlesztőit, így ‘ nem lehet ez nyilvánvaló.

Válasz

Mi a célja a GIL-nek?

A CAPI dokumentáció ezt mondja ki a témáról:

A Python tolmács nem teljesen szálbiztonságos . A többszálas Python programok támogatásához van egy globális zár, az úgynevezett globális tolmács-zár vagy GIL, amelyet az aktuális szálnak kell tartania, mielőtt biztonságosan elérheti a Python-objektumokat. A zárolás nélkül a legegyszerűbb műveletek is problémákat okozhatnak egy többszálas programban: például amikor két szál egyszerre növeli ugyanazon objektum referenciaszámát, a referenciaszám végül csak egyszer növekedhet kétszer.

Más szavakkal, a GIL megakadályozza az állam korrupcióját. A Python programok soha ne hozzanak létre szegmentálási hibát, mert csak memóriában biztonságos műveletek engedélyezettek. A GIL kiterjeszti ezt a biztosítékot a többszálú programokra is.

Melyek az alternatívák?

Ha a GIL célja az állam védelme a korrupciótól, akkor az egyik nyilvánvaló alternatíva a sokkal finomabb szemcsés zár; talán objektumonként. A probléma ezzel az, hogy bár bebizonyosodott, hogy növeli a több szálon futó programok teljesítményét, több rezsi és egyszálú programok szenvednek emiatt.

Megjegyzések

  • Nagyszerű lenne, ha hagynánk, hogy a felhasználó futtasson egy programot egy tolmács opcióval, amely a gil helyettesítését finom szemcsés zárra cseréli, és valahogy tudja – csak olvasható módon -, hogy az aktuális folyamatot felvetették-e vagy sem gil.
  • A GIL ellenére sikerült egy szegmens hibát előállítani egy többszálú programban a pyodbc modul gondatlan használata miatt. Ezért ” soha nem szabad szegmentálási hibát produkálni ” tévedés.

Vélemény, hozzászólás?

Az email címet nem tesszük közzé. A kötelező mezőket * karakterrel jelöltük