Proč byl Python psán s GIL?

Zdá se, že zámek globálního tlumočníka (GIL) je často uváděn jako hlavní důvod, proč je vlákno a podobně v Pythonu obtížné – což vyvolává otázku „Proč se to stalo na prvním místě?“

Protože nejsem programátor, nemám ponětí, proč by to mohlo být – jaká byla logika zavedení GIL?

Komentáře

  • Článek Wikipedie uvádí, že “ GIL může být významnou překážkou paralelismu – cena zaplacená za dynamiku jazyka “ a dále říká, že “ Důvody pro použití takového zámku zahrnují: zvýšenou rychlost jednovláknových programů (není nutné získávat nebo uvolňovat zámky na všech datových strukturách samostatně) a snadnou integraci knihoven C, které obvykle jsou není bezpečné pro vlákna. “
  • @RobertHarvey, dynamismus nemá co dělat s tím. Problém je v mutaci.
  • stackoverflow.com/questions/265687/…
  • Nelze ‚ pomoci cítit, že stejně jako nedostatek nepodepsaných čísel v jazyce Java ‚ měl zabránit lidem, kteří ‚ nevědí, co ‚ střílí do nohy. Bohužel každý, kdo ví, co dělá ‚, má nedostatečný jazyk, což je skutečná škoda, protože Python skáče mnoha jinými způsoby
  • @Basic musí existovat nějaký standardní způsob, jak se vypořádat s bajtovými poli v Javě (nepoužíval jsem to ‚ dlouho), abych zvládl kryptoměnu. Python (například) nemá ‚ t podepsaná čísla, ale já bych se ‚ s tím ani nepokoušel dělat bitové operace, protože existují lepší způsoby.

Odpověď

Existuje několik implementací Pythonu, například CPython, IronPython, RPython, atd.

Některé z nich mají GIL, jiné nikoli. Například CPython má GIL:

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

Aplikace napsané v programovacích jazycích s GIL mohou být navrženy tak, aby používaly samostatné procesy k dosažení úplné paralelnosti, protože každý proces má svého vlastního tlumočníka a má zase svůj vlastní GIL.

Výhody GIL

  • Zvýšená rychlost programů s jedním vláknem.
  • Snadná integrace knihoven C, které obvykle nejsou bezpečné pro vlákna.

Proč Python (CPython a další) používá GIL

V CPythonu je zámek globálního tlumočníka neboli GIL mutex, který brání tomu, aby více nativních vláken provádělo bajtové kódy Pythonu najednou. Tento zámek je nezbytný hlavně proto, že správa paměti CPython není bezpečná pro vlákna.

GIL je kontroverzní, protože v určitých situacích brání vícevláknovým programům CPython plně využívat výhody víceprocesorových systémů. Pamatujte, že potenciální blokování nebo dlouhodobé operace, jako jsou vstupy a výstupy, zpracování obrazu a rozbití čísel NumPy, probíhají mimo GIL. Proto pouze v multithreadových programech, které tráví hodně času uvnitř GIL, interpretujíc bajtkód CPython, se GIL stává úzké místo.

Python má GIL na rozdíl od jemnozrnného zamykání z několika důvodů:

  • Je to rychlejší v případě jednoho vlákna.

  • Je to rychlejší v případě více vláken pro programy vázané na I / O.

  • Je to rychlejší v případě více vláken pro programy vázané na CPU jejich výpočetně náročná práce v knihovnách C.

  • Dělá Psaní rozšíření C je snazší: nebude možné přepínat vlákna Pythonu kromě případů, kdy to dovolíte (tj. mezi makry Py_BEGIN_ALLOW_THREADS a Py_END_ALLOW_THREADS).

  • Díky tomu je snazší zabalit C knihovny. Nemusíte si dělat starosti s bezpečností podprocesů. Pokud knihovna není bezpečná pro podprocesy, jednoduše necháte GIL uzamčen, když jej budete volat.

GIL může být uvolněn rozšířeními C. Standardní knihovna Pythonu uvolňuje GIL kolem každého blokujícího volání I / O. GIL tedy nemá žádné důsledky pro výkon serverů vázaných na I / O. Můžete tedy vytvářet síťové servery v Pythonu pomocí procesů (fork), vláken nebo asynchronních I / O a GIL vám nebude překážet.

Numerické knihovny v C nebo Fortran lze podobně nazývat pomocí GIL propuštěn. Zatímco vaše rozšíření C čeká na dokončení FFT, interpret provede další vlákna Pythonu.GIL je tedy i v tomto případě jednodušší a rychlejší než jemnozrnné zamykání. To představuje převážnou část numerické práce. Rozšíření NumPy uvolňuje GIL, kdykoli je to možné.

Vlákna jsou obvykle špatný způsob psaní většiny serverových programů. Je-li náklad nízký, je vidlice snazší. Pokud je zatížení vysoké, je lepší asynchronní I / O a programování řízené událostmi (např. Pomocí Twisted framework Pythonu). Jedinou výmluvou pro použití vláken je nedostatek os.fork ve Windows.

GIL je problém, pokud a pouze v případě, že pracujete na CPU v čistém Pythonu. Zde můžete získat čistší design pomocí procesů a předávání zpráv (např. Mpi4py). K dispozici je také modul „zpracování“ v sýru Python shop, který poskytuje procesům stejné rozhraní jako vlákna (tj. vyměňte threading.Thread za processing.Process).

Vlákna lze použít k udržení odezvy GUI bez ohledu na GIL. Pokud GIL zhoršuje váš výkon (viz výše uvedená diskuse), můžete nechat své vlákno vytvořit proces a počkat na jeho dokončení.

Komentáře

  • Zní to jako kyselé hrozny pro mě. Python nemůže ‚ správně dělat vlákna, takže si vymyslíte důvody, proč jsou vlákna zbytečná nebo dokonce špatná. “ Pokud zatížení je nízká, fo rking je snadnější „, vážně? A GIL je “ rychlejší “ ve všech těchto případech, pouze pokud trváte na použití GC pro počítání referencí.
  • s/RPython/PyPy/g. @MichaelBorgwardt Uvedení důvodů pro GIL je tak trochu otázkou, že? ‚ že? I když bych souhlasil, že část obsahu této odpovědi (zejména diskuse o alternativách) je mimo věc. A k lepšímu nebo k horšímu je refinancování téměř nemožné se ho zbavit – je hluboce zakořeněno v celém API a kódové základně; je ‚ téměř nemožné se ho zbavit, aniž byste přepsali polovinu kódu a rozbili celý externí kód.
  • Don ‚ Nezapomeňte na knihovnu multiprocessing – standardní od 2.6. It ‚ s pracovní fondy jsou super-úhledná abstrakce pro některé jednoduché typy paralelismu.
  • @alcalde Pouze pokud ‚ Nevíte, co ‚ děláte a / nebo nechcete ‚, aby vaše vlákna byla schopna spolupracovat / komunikovat. Jinak je to ‚ královskou bolestí v pozadí, zejména s ohledem na režii zahájení nového procesu v některých operačních systémech. Máme servery s 32 jádry, takže abychom je mohli plně využít v CPython, potřebuji ‚ 32 procesů. To ‚ není “ dobré řešení “ to ‚ je hack, který obchází CPython ‚ s nedostatečnostmi.
  • Skutečnost, že vlákna existují na jiných platformách než Windows, by měla být dostatečným důkazem toho, že forking není ‚ není adekvátní v každé situaci.

Odpovědět

První vypnuto: Python nemá GIL. Python je programovací jazyk. Programovací jazyk je sada abstraktních matematických pravidel a omezení. Ve specifikaci jazyka Python není nic, co by říkalo, že musí existovat GIL.

Existuje mnoho různých implementací Pythonu. Některé mají GIL, jiné nikoli.

Jedním jednoduchým vysvětlením, jak mít GIL, je to, že psaní souběžného kódu je těžké. Umístěním obrovského zámku kolem kódu vynutíte, aby vždy běžel sériově. Problém vyřešen!

Zejména v CPythonu je jedním důležitým cílem usnadnit rozšíření tlumočníka o pluginy napsané v C. Opět platí, že psaní souběžného kódu je těžké, takže zaručením, že nebude existovat žádný souběžnost, usnadňuje psaní rozšíření pro tlumočníka. Mnohé z těchto rozšíření jsou navíc jen tenkými obaly kolem existujících knihoven, které možná nebyly napsány s ohledem na souběžnost.

Komentáře

  • To ‚ má stejný argument jako Java ‚ nedostatek nepodepsaných číselných typů – vývojáři si myslí, že všichni ostatní jsou hloupější než oni …
  • @Basic – věřte tomu nebo ne, i když ‚ nejste opravdu, opravdu hloupí, ukazuje se, že mít jazyk, který umožňuje zjednodušení předpokladů, které znamenají, že ne ‚ Přemýšlet o určitých věcech, aby fungovaly, je stále užitečná věc.CPython je skvělý pro určité věci, včetně jednoduchých vícevláknových aplikací (kde je program vázán na IO, což je mnoho, a proto na GIL nezáleží ‚), protože rozhodnutí o návrhu, která učinila GIL nejlepším řešením také usnadňuje programování těchto aplikací, zejména skutečnost, že podporuje atomové operace na kolekcích .
  • @Jules Ano, ‚ je velmi šikovný, dokud tyto schopnosti nepotřebujete. cpython ‚ s “ preferované “ řešení “ stačí jej napsat v jiném jazyce, jako je c ++ „, což znamená, že ztratíte všechny výhody pythonu. Pokud ‚ píšete polovinu svého kódu v jazyce C ++, tak proč začít od Pythonu? Jistě, pro malé projekty API / lepidla je to ‚ rychlé a snadné a pro ETL to ‚ nemá obdoby, ale ‚ s není vhodný pro nic, co vyžaduje těžké zvedání. Stejné jako používání Javy pro komunikaci s hardwarem … ‚ je téměř komické, přes které musíte přeskočit.
  • @Basic Jeden z Pythonu ‚ s, a tedy v širším smyslu CPython ‚ základní filozofií je učinit technologii “ přátelskou a snadno použitelné „. Paralelní programování bez globálního zámku není to. Vzhledem k tomu, že existuje mnoho implementací bez GIL, má smysl zajistit alespoň jednu implementaci, která ji má.
  • Říkáte “ má smysl alespoň poskytnout jedna implementace, která ho má. “ líbí se ‚ se zřejmým závěrem, ale žádný jiný jazyk mi ‚ Tímto způsobem si uvědomuji své vývojáře, takže ‚ nemusí být to zřejmé.

Odpověď

Jaký je účel GIL?

Dokumentace CAPI na toto téma říká:

Interpret Pythonu není plně bezpečný pro vlákna . Aby bylo možné podporovat vícevláknové programy Pythonu, existuje globální zámek, který se nazývá globální tlumočník nebo GIL, který musí aktuální vlákno držet, než bude moci bezpečně přistupovat k objektům Pythonu. Bez zámku by i ty nejjednodušší operace mohly způsobit problémy ve vícevláknovém programu: například když dvě vlákna současně zvyšují počet odkazů stejného objektu, počet odkazů může skončit tak, že se zvýší pouze jednou místo dvakrát.

Jinými slovy, GIL brání poškození státu. Programy v Pythonu by nikdy neměly způsobit poruchu segmentace, protože jsou povoleny pouze bezpečné operace paměti. GIL rozšiřuje tuto záruku na vícevláknové programy.

Jaké jsou alternativy?

Pokud je účelem GIL chránit stát před poškozením, pak je zřejmou alternativou zamknout se na mnohem jemnější zrno; možná na úrovni jednotlivých objektů. Problém je v tom, že ačkoliv bylo prokázáno, že zvyšuje výkon vícevláknových programů, má vyšší režii a v důsledku toho trpí programy s jedním vláknem.

Komentáře

  • Bylo by skvělé nechat uživatele spustit program s možností tlumočníka, který nahradí gil za jemnozrnný zámek, a nějak vědět – pouze pro čtení – zda byl aktuální proces vyvolán s nebo bez gil.
  • I přes GIL se mi kvůli neopatrnému použití modulu pyodbc podařilo ve vícevláknovém programu vytvořit chybu segmentace. “ by tedy nikdy neměl způsobit chybu segmentace. “ je klam.

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *