Hvorfor blev Python skrevet med GIL?

Den globale tolkelås (GIL) synes ofte at blive citeret som en væsentlig årsag til, at threading og lignende er en vanskelig trick i Python – hvilket rejser spørgsmålet “Hvorfor blev det i første omgang gjort?”

Da jeg ikke var programmerer, har jeg ingen anelse om, hvorfor det kan være – hvad var logikken bag at lægge GIL i?

Kommentarer

  • Wikipedia-artikel siger, at ” GIL kan være en væsentlig barriere for parallelisme – en pris, der betales for at have dynamikken i sproget ” , og fortsætter med at sige, at ” Årsagerne til at anvende en sådan lås inkluderer: øget hastighed for programmer med enkelt gevind (ingen nødvendighed at erhverve eller frigive låse på alle datastrukturer separat) og nem integration af C-biblioteker, der normalt er ikke trådsikker. ”
  • @RobertHarvey, Dynamisme har intet at gøre med det. Problemet er mutation.
  • stackoverflow.com/questions/265687/…
  • Kan ‘ ikke hjælpe med at føle, at ligesom Java ‘ mangler usignerede tal, var det beregnet til at forhindre folk, der ikke ‘ ved ikke hvad de ‘ laver og skyder sig selv i foden. Desværre, enhver, der ved ved, hvad de ‘ laver, får et mangelfuldt sprog, hvilket er en skam, fordi Python klipper på så mange andre måder
  • @Basic der skal være en standard måde at håndtere byte-arrays på Java (jeg har ikke ‘ brugte det ikke i lang tid) for at lave kryptomatematik. Python (for eksempel) har ikke ‘ ikke underskrevne numre, men jeg ville ikke ‘ ikke engang prøve at gøre bitvis ops med det, fordi der er bedre måder.

Svar

Der er flere implementeringer af Python, for eksempel CPython, IronPython, RPython, osv.

Nogle af dem har en GIL, nogle har ikke. F.eks. har CPython GIL:

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

Applikationer skrevet på programmeringssprog med en GIL kan designes til at bruge separate processer for at opnå fuld parallelitet, da hver proces har sin egen tolk og har til gengæld sin egen GIL.

Fordele ved GIL

  • Øget hastighed for enkelttrådede programmer.
  • Nem integration af C-biblioteker, der normalt ikke er trådsikre.

Hvorfor bruger Python (CPython og andre) GIL

I CPython er den globale tolkelås, eller GIL, en mutex, der forhindrer flere indfødte tråde i at udføre Python-bytecodes på én gang. Denne lås er hovedsagelig nødvendig, fordi CPythons hukommelsesadministration ikke er trådsikker.

GIL er kontroversiel, fordi den forhindrer flertrådede CPython-programmer i at drage fuld fordel af multiprocessorsystemer i visse situationer. Bemærk, at potentielt blokering eller langvarige operationer, såsom I / O, billedbehandling og NumPy nummer-knasning, sker uden for GIL. Derfor er det kun i multitrådede programmer, der bruger meget tid inde i GIL og fortolker CPython bytecode, at GIL bliver en flaskehals.

Python har en GIL i modsætning til finkornet låsning af flere årsager:

  • Det er hurtigere i entrådssagen.

  • Det er hurtigere i multi-threaded-sagen til i / o-bundne programmer.

  • Det er hurtigere i multi-threaded-sagen til cpu-bundne programmer, der gør deres computerintensive arbejde i C-biblioteker.

  • Det gør C-udvidelser lettere at skrive: der vil ikke være nogen switch af Python-tråde undtagen hvor du tillader det at ske (dvs. mellem Py_BEGIN_ALLOW_THREADS og Py_END_ALLOW_THREADS makroerne).

  • Det gør indpakning af C-biblioteker lettere. Du behøver ikke bekymre dig om trådsikkerhed. Hvis biblioteket ikke er trådsikkert, skal du blot holde GIL låst, mens du kalder det.

GIL kan frigives af C.-udvidelser. Pythons standardbibliotek frigiver GIL omkring hvert blokerende i / o-opkald. Således har GIL ingen konsekvens for ydeevne af i / o-bundne servere. Du kan således oprette netværksservere i Python ved hjælp af processer (fork), tråde eller asynkron i / o, og GIL kommer ikke i vejen for dig.

Numeriske biblioteker i C eller Fortran kan ligeledes kaldes med GIL frigivet. Mens din C-udvidelse venter på, at en FFT er færdig, udfører tolken andre Python-tråde.En GIL er således lettere og hurtigere end finkornet låsning også i dette tilfælde. Dette udgør størstedelen af det numeriske arbejde. NumPy-udvidelsen frigiver GIL, når det er muligt.

Tråde er normalt en dårlig måde at skrive de fleste serverprogrammer på. Hvis belastningen er lav, er gaffel lettere. Hvis belastningen er høj, er asynkron i / o og hændelsesdrevet programmering (f.eks. Ved hjælp af Pythons Twisted framework) bedre. Den eneste undskyldning for at bruge tråde er manglen på os.fork i Windows.

GIL er et problem, hvis og kun hvis du laver CPU-intensivt arbejde i ren Python. Her kan du få renere design ved hjælp af processer og meddelelsesoverførsel (f.eks. Mpi4py). Der er også et “behandlings” -modul i Python-ost shop, der giver processer den samme grænseflade som tråde (dvs. udskift threading.Tråd med processering.Process).

Tråde kan bruges til at opretholde lydhørhed af en GUI uanset GIL. Hvis GIL forringer din ydeevne (jf. diskussionen ovenfor), kan du lade din tråd gyde en proces og vente på, at den er færdig.

Kommentarer

  • Lyder som sure druer for mig. Python kan ‘ ikke udføre tråde ordentligt, så du udgør grunde til, at tråde er unødvendige eller endda dårlige. ” Hvis belastningen er lav, fo rking er lettere “, seriøst? Og GIL er ” hurtigere ” kun for alle disse tilfælde, hvis du insisterer på at bruge referencetælling GC.
  • s/RPython/PyPy/g. @MichaelBorgwardt At give grunde til, at GIL er noget af spørgsmålet, er det ikke ‘? Selvom jeg er enig i, at noget af indholdet af dette svar (nemlig diskussion af alternativer) er uden for sagen. Og på godt og ondt er genoptælling nu næsten umuligt at slippe af med – det er dybt indgroet i hele API og kodebase; det ‘ er næsten umuligt at slippe af med det uden at omskrive halvdelen af koden og bryde alt ekstern kode.
  • Don ‘ glem ikke multiprocessing biblioteket – standard siden 2.6. Det ‘ s medarbejderpuljer er en superglat abstraktion til nogle enkle typer parallelisme.
  • @alcalde Kun hvis du ikke ‘ ved ikke, hvad du ‘ laver, og / eller du ‘ ikke ønsker, at dine tråde skal kunne arbejde sammen / kommunikere. Ellers er det ‘ en kongelig smerte på bagsiden, især i betragtning af omkostningerne ved at starte en ny proces på nogle operativsystemer. Vi har servere med 32 kerner, så for at udnytte dem fuldt ud i CPython I ‘ behøver 32 processer. At ‘ ikke er en ” god løsning ” det ‘ et hack for at arbejde omkring CPython ‘ mangler.
  • Det faktum, at der findes tråde på andre platforme end Windows, skal være et bevis nok til, at gaffel ikke er ‘ t er tilstrækkelig i enhver situation.

Svar

Først off: Python har ikke en GIL. Python er et programmeringssprog. Et programmeringssprog er et sæt abstrakte matematiske regler og begrænsninger. Der er intet i Python Language Specification, der siger, at der skal være en GIL.

Der er mange forskellige implementeringer af Python. Nogle har en GIL, andre ikke.

En simpel forklaring på at have en GIL er, at det er svært at skrive samtidig kode. Ved at placere en kæmpe lås omkring din kode, tvinger du den til altid at køre serielt. Problem løst!

Især i CPython er et vigtigt mål at gøre det let at udvide tolken med plugins skrevet i C. Igen er det svært at skrive samtidig kode, så ved at garantere, at der ikke er nogen samtidig gør det det lettere at skrive udvidelser til tolken. Plus, mange af disse udvidelser er bare tynde indpakninger omkring eksisterende biblioteker, som muligvis ikke er skrevet med samtidighed i tankerne.

Kommentarer

  • At ‘ er det samme argument som Java ‘ mangler usignerede numeriske typer – udviklerne mener, at alle andre er dummere end de er …
  • @Basic – tro det eller ej, selv når du ‘ ikke er rigtig, virkelig dum, viser det sig at have et sprog, der gør forenklende antagelser, der betyder, at du ikke ‘ Tænk ikke over bestemte ting for at få dem til at fungere er stadig en nyttig ting.CPython er fantastisk til visse ting, herunder enkle multitrådede applikationer (hvor programmet er IO-bundet, hvilket mange er, og derfor betyder GIL ikke ‘ t), fordi de designbeslutninger, der tog GIL den bedste løsning gør det også lettere at programmere disse applikationer, især det faktum, at det understøtter atomoperationer på samlinger .
  • @Jules Ja, det ‘ er meget praktisk lige indtil du har brug for disse muligheder. cpython ‘ s ” foretrukket ” løsning af ” skriv det bare på et andet sprog som c ++ ” betyder det, at du mister hver enkelt python-fordel. Hvis du ‘ skriver halvdelen af din kode i c ++, hvorfor så starte fra Python? Sikker på, for små API / lim projekterer det ‘ hurtigt og nemt, og for ETL er det ‘ noget andet, men det ‘ er ikke egnet til noget, der kræver tunge løft. Samme som at bruge Java til at tale med hardware … Det ‘ er næsten komiske de bøjler, du er nødt til at springe igennem.
  • @Basic One af Python ‘ s og dermed i vid udstrækning CPython ‘ s kernefilosofier er at gøre teknologien ” venlig og let at bruge “. Parallel programmering uden global lås er ikke det. I betragtning af at der er mange implementeringer uden GIL, er det fornuftigt at i det mindste give en implementering, der har det.
  • Du siger ” det giver mening at i det mindste give en implementering, der har det. ” kan lide det ‘ er den oplagte konklusion, men intet andet sprog jeg ‘ er opmærksom på at hæmme udviklerne på denne måde, så det kan ‘ t være det indlysende.

Svar

Hvad er formålet med en GIL?

CAPI-dokumentationen har dette at sige om emnet:

Python-tolken er ikke fuldt trådsikker . For at understøtte Python-programmer med flere gevind, er der en global lås, kaldet den globale tolkelås eller GIL, der skal holdes af den aktuelle tråd, før den sikkert kan få adgang til Python-objekter. Uden låsen kan selv de enkleste operationer medføre problemer i et program med flere gevind: For eksempel, når to tråde samtidigt øger referencetællingen for det samme objekt, kan referencetallet kun ende med at blive forøget en gang i stedet for to gange.

Med andre ord forhindrer GIL statskorruption. Python-programmer bør aldrig producere en segmenteringsfejl, fordi kun hukommelsessikker drift er tilladt. GIL udvider denne sikkerhed til programmer med flere tråde.

Hvad er alternativerne?

Hvis formålet med GIL er at beskytte staten mod korruption, så er et oplagt alternativ at låse et meget finere korn; måske på niveau pr. objekt. Problemet med dette er, at selvom det er blevet demonstreret at øge ydeevnen for programmer med flere tråde, har det flere omkostninger, og enkelttrådede programmer lider som et resultat. = “kommentarer”>

  • Det ville være dejligt at lade en bruger køre et program med en tolkemulighed, der erstatter gil til finkornet lås, og på en eller anden måde ved – på en let måde – om den aktuelle proces blev hævet med eller uden gil.
  • På trods af GIL formåede jeg at producere en segmenteringsfejl i et multitrådet program på grund af skødesløs brug af modul pyodbc. Således bør ” aldrig producere en segmenteringsfejl ” er en fejlslutning.
  • Skriv et svar

    Din e-mailadresse vil ikke blive publiceret. Krævede felter er markeret med *