Hvordan tråder arbeid i Python, og hva er vanlige Python-threading spesifikke fallgruvene?

stemmer
75

Jeg har prøvd å pakke hodet mitt rundt hvordan tråder fungerer i Python, og det er vanskelig å finne god informasjon om hvordan de opererer. Jeg kan bare mangle en link eller noe, men det virker som den offisielle dokumentasjonen er ikke veldig grundig om emnet, og jeg har ikke vært i stand til å finne en god skrive opp.

Fra hva jeg kan fortelle, kan bare en tråd skal kjøre på en gang, og den aktive tråden skifter hver 10 instruksjoner eller så?

Der er det en god forklaring, eller kan du gi en? Det ville også være veldig fint å være klar over vanlige problemer som du kjører inn mens du bruker tråder med Python.

Publisert på 27/08/2008 klokken 23:44
kilden bruker
På andre språk...                            


7 svar

stemmer
46

Ja, på grunn av den globale Interpreter Lock (GIL) det kan bare kjøre en tråd om gangen. Her er noen linker med noen innsikt om dette:

Fra den siste linken en interessant sitat:

La meg forklare hva alt dette betyr. Tråder kjøre i samme virtuelle maskinen, og dermed kjøre på samme fysiske maskin. Prosesser kan kjøres på den samme fysiske maskin eller i en annen fysisk maskin. Hvis du arkitekten din søknad rundt tråder, du har gjort noe for å få tilgang til flere maskiner. Så kan du skalere til så mange kjerner er på den ene maskinen (som vil være ganske mange over tid), men for å virkelig nå nett skalaer, må du løse flere maskin problem uansett.

Hvis du ønsker å bruke flerkjerne, pyprocessing definerer en prosess basert API for å gjøre virkelige parallellisering. Den PEP inkluderer også noen interessante benchmarks.

Svarte 28/08/2008 kl. 00:19
kilden bruker

stemmer
35

Python er et ganske enkelt språk å tråden i, men det finnes begrensninger. Den største tingen du trenger å vite om er Global Interpreter Lock. Dette gjør at bare en tråd for å få tilgang til tolk. Dette betyr to ting: 1) du sjelden gang finner deg selv ved hjelp av en lås uttalelse i python og 2) hvis du ønsker å dra nytte av flerprosessorsystemer, må du bruke separate prosesser. EDIT: Jeg må også påpeke at du kan sette noen av koden i C / C ++ hvis du ønsker å komme seg rundt i GIL også.

Dermed må du re-vurdere hvorfor du ønsker å bruke tråder. Hvis du ønsker å Parallell appen din for å dra nytte av dual-core arkitektur, må du vurdere å bryte app opp i flere prosesser.

Hvis du ønsker å forbedre reaksjonsevne, bør du vurdere å bruke tråder. Det finnes andre alternativer skjønt, nemlig microthreading . Det er også noen rammer som du bør se nærmere på:

Svarte 28/08/2008 kl. 00:00
kilden bruker

stemmer
19

Nedenfor er en grunnleggende gjenger prøve. Det vil gyte 20 tråder; hver tråd vil generere sin trådnummer. Kjør den og observere i hvilken rekkefølge de skrives ut.

import threading
class Foo (threading.Thread):
    def __init__(self,x):
        self.__x = x
        threading.Thread.__init__(self)
    def run (self):
          print str(self.__x)

for x in xrange(20):
    Foo(x).start()

Som du har hintet om at Python tråder er implementert gjennom tids slicing. Dette er hvordan de får "parallelt" effekt.

I mitt eksempel min Foo klasse strekker tråden, jeg så implementere runmetoden, som er der koden som du ønsker å kjøre i en tråd går. For å starte tråden du ringe start()på tråden objektet, som automatisk starter en runmetode ...

Selvfølgelig er dette bare grunnleggende. Du vil etter hvert ønsker å lære om semaforer, mutexes, og låser for tråden synkronisering og meldingsutveksling.

Svarte 27/08/2008 kl. 23:52
kilden bruker

stemmer
10

Bruk tråder i python hvis de enkelte arbeidstakere gjør I / O-bundet operasjoner. Hvis du prøver å skalere over flere kjerner på en maskin enten finne en god IPC rammeverk for python eller velge et annet språk.

Svarte 28/08/2008 kl. 02:34
kilden bruker

stemmer
3

Merk: uansett hvor jeg nevne threadjeg mener spesielt tråder i python til uttrykkelig angitt.

Tråder jobbe litt annerledes i python hvis du kommer fra C/C++bakgrunnen. I python, kan bare én tråd være i rennende tilstand på et gitt gangs betyr Tråder i python kan ikke virkelig utnytte kraften av flere prosessorkjerner siden by design er det ikke mulig for tråder å kjøre parallelt på flere kjerner.

Som minnehåndtering i python er ikke trådsikker hver tråd kreve en eksklusiv tilgang til datastrukturene i python interpreter.This eksklusiv tilgang er ervervet ved hjelp av en mekanisme kalt (global interpretr lås) .GIL

Why does python use GIL?

For å hindre at flere tråder fra å få tilgang tolk tilstand samtidig og at den skader tolk tilstand.

Tanken er når en tråd blir utført (selv om det er hovedtråden) , en GIL er ervervet, og etter en forutbestemt tidsintervall GIL frigjøres av gjeldende tråd og gjenervervet av en annen tråd (hvis noen).

Why not simply remove GIL?

Det er ikke at det er umulig å fjerne GIL, det bare at i prcoess å gjøre det vi ender opp med å sette mutiple låser inne tolk for å serial tilgang, som gjør selv en enkelt gjenget søknad mindre performant.

slik at kostnaden for å fjerne GIL er betalt av ved redusert ytelse av en enkelt gjenget applikasjon, som er aldri ønskelig.

So when does thread switching occurs in python?

Tråd bryter oppstår når GIL er released.So når er GIL Utgitt? Det er to scenarier for å ta hensyn til.

Hvis en tråd gjør CPU Bound operasjoner (Ex bildebehandling).

I eldre versjoner av python, Thread veksling brukes til å skje etter en fast ingen av python instructions.It var som standard satt til 100.Det viste seg at det er ikke en veldig god politikk for å bestemme når du bytter skal skje siden den tid brukt gjennomføring av en enkelt instruksjon kan veldig vilt fra millisekund til enda en second.Therefore slippe GIL etter hver 100instruksjoner uavhengig av tiden de tar å gjennomføre er en dårlig politikk.

I nye versjoner stedet for å bruke antall instruksjoner som en beregning for å bytte tråden, er en konfigurerbar tidsintervall anvendt. Standard bryteren intervallet er 5 milliseconds.you kan få den aktuelle bryteren intervall hjelp sys.getswitchinterval(). Dette kan endres ved hjelpsys.setswitchinterval()

Hvis en tråd gjør noen IO Bundet Operations (Ex filsystem tilgang eller
nettverks IO)

GIL er utgivelsen når tråden venter på noen for IO operasjon for å bli ferdig.

Which thread to switch to next?

Det tolkeren ikke har sin egen scheduler.which tråd blir planlagt ved slutten av intervallet er operativsystemets avgjørelse. .

Svarte 30/03/2018 kl. 11:47
kilden bruker

stemmer
3

En enkel løsning på GIL er multi modulen. Den kan brukes som et fall i erstatning for gjengene modulen men benytter flere Tolkeprosesser i stedet for gjenger. På grunn av dette er det en litt mer overhead enn vanlig threading for enkle ting, men det gir deg fordelen av virkelige parallellisering hvis du trenger det. Det lett skalerer også til flere fysiske maskiner.

Hvis du trenger virkelig stor skala parallellisering enn jeg ville se videre, men hvis du bare ønsker å skalere til alle kjernene i en datamaskin eller noen annen som uten alt arbeidet som ville gå inn å implementere en mer helhetlig ramme, enn dette er for deg .

Svarte 06/02/2014 kl. 16:19
kilden bruker

stemmer
2

Prøv å huske at GIL er satt til avstemning rundt hver så ofte for å gjøre vise utseendet på flere oppgaver. Denne innstillingen kan finjusteres, men jeg har forslaget om at det skal være arbeid som gjengene gjør eller mange kontekst brytere kommer til å skape problemer.

Jeg vil gå så langt som å foreslå flere foreldre på prosessorer og prøve å holde ut jobber på den samme kjernen (e).

Svarte 28/07/2009 kl. 22:40
kilden bruker

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more