Programmering

Hvordan bruke asyncio i Python

Pythons asynkrone programmeringsfunksjonalitet, eller forkortelse async, lar deg skrive programmer som får mer arbeid gjort ved ikke å vente på at uavhengige oppgaver skal fullføres. De asyncio biblioteket som følger med Python, gir deg verktøyene for å bruke async for behandling av disk eller nettverks I / O uten å få alt annet til å vente.

asyncio gir to typer APIer for å håndtere asynkrone operasjoner:høy level oglavt nivå. API-er på høyt nivå er de mest nyttige, og de kan brukes i det bredeste spekteret av applikasjoner. API-er på lavt nivå er kraftige, men også komplekse, og brukes sjeldnere.

Vi konsentrerer oss om API-er på høyt nivå i denne artikkelen. I avsnittene nedenfor går vi gjennom de mest brukte API-ene på høyt nivå iasyncio, og viser hvordan de kan brukes til vanlige operasjoner som involverer asynkrone oppgaver.

Hvis du er helt ny innen asynkronisering i Python, eller du kan bruke en forfriskning på hvordan det fungerer, kan du lese introduksjonen min til Python async før du dykker inn her.

Kjør coroutines og oppgaver i Python

Naturligvis den vanligste bruken for asyncio er å kjøre de asynkrone delene av Python-skriptet. Dette betyr å lære å jobbe med coroutines og oppgaver.

Pythons async-komponenter, inkludert coroutines og oppgaver, kan bare brukes med andre async-komponenter, og ikke med konvensjonell synkron Python, så du trengerasyncio for å bygge bro over gapet. For å gjøre dette bruker duasyncio.run funksjon:

importer asyncio

async def hoved ():

utskrift ("Venter i 5 sekunder.")

for _ innen rekkevidde (5):

venter på asyncio.sleep (1)

skrive ut (".")

utskrift ("Ferdig ventet.")

asyncio.run (main ())

Dette gårhoved(), sammen med noen coroutineshoved() fyrer av og venter på at resultatet skal komme tilbake.

Som en generell regel bør et Python-program bare ha ett.løpe() uttalelse, akkurat som et Python-program bare skal ha enhoved() funksjon. Async, hvis det brukes uforsiktig, kan gjøre kontrollflyten til et program vanskelig å lese. Å ha et enkelt inngangspunkt til programmets asynkroniseringskode hindrer at ting blir hårete.

Async-funksjoner kan også planlegges somoppgaver, eller gjenstander som pakker coroutines og hjelper med å kjøre dem.

async def min_oppgave ():

gjør noe()

oppgave = asyncio.create_task (min_oppgave ())

min_oppgave () kjøres deretter i hendelsessløyfen, med resultatene lagret ioppgave.

Hvis du bare har en oppgave du vil få resultater fra, kan du brukeasyncio.wait_for (oppgave) å vente til oppgaven er ferdig, og bruk derettertask.result () for å hente resultatet. Men hvis du har planlagt en rekke oppgaver som skal utføres, og du vil vente påalle av dem for å fullføre, brukeasyncio.wait ([oppgave1, oppgave2]) for å samle resultatene. (Merk at du kan angi en tidsavbrudd for operasjonene hvis du ikke vil at de skal kjøre forbi en viss tidsperiode.)

Administrer en asynkroniseringshendelsessløyfe i Python

En annen vanlig bruk forasyncio er å administrere asynkroniseringenhendelsessløyfe. Hendelsessløyfen er et objekt som kjører asynkroniseringsfunksjoner og tilbakeringing; den opprettes automatisk når du brukerasyncio.run (). Du vil vanligvis bare bruke en asynkroniseringshendelsessløyfe per program, igjen for å holde ting håndterbart.

Hvis du skriver mer avansert programvare, for eksempel en server, trenger du tilgang på lavere nivå til hendelsessløyfen. For å oppnå dette kan du "løfte hetten" og jobbe direkte med hendelsessløyfens indre. Men for enkle jobber trenger du ikke.

Les og skriv data med strømmer i Python

De beste scenariene for async er langvarige nettverksoperasjoner, der applikasjonen kan blokkere å vente på at en annen ressurs skal returnere et resultat. Til den slutten,asyncio tilbyr streams, som er mekanismer på høyt nivå for å utføre nettverks I / O. Dette inkluderer å fungere som en server for nettverksforespørsler.

asyncio bruker to klasser,StreamReader ogStreamWriter, å lese og skrive fra nettverket på høyt nivå. Hvis du vil lese fra nettverket, vil du brukeasyncio.open_connection () for å åpne forbindelsen. Den funksjonen returnerer en tusenvis avStreamReader ogStreamWriter gjenstander, og du vil bruke.lese() og.skrive() metoder på hver for å kommunisere.

Bruk for å motta tilkoblinger fra eksterne verterasyncio.start_server (). De asyncio.start_server () funksjon tar som et argument en tilbakeringingsfunksjon,client_connected_cb, som kalles når den mottar en forespørsel. Den tilbakeringingsfunksjonen tar forekomster avStreamReader og StreamWriter som argumenter, slik at du kan håndtere lese- / skrivelogikken for serveren. (Se her for et eksempel på en enkel HTTP-server som brukerasyncio-drevetaiohttp bibliotek.)

Synkroniser oppgaver i Python

Asynkrone oppgaver har en tendens til å løpe isolert, men noen ganger vil du at de skal kommunisere med hverandre.asyncio gir køer og flere andre mekanismer for synkronisering mellom oppgaver:

  • Køerasyncio køer tillater asynkrone funksjoner å stille opp Python-objekter som skal konsumeres av andre async-funksjoner - for eksempel å distribuere arbeidsmengder mellom forskjellige typer funksjoner basert på deres atferd.
  • Primitiver for synkronisering: Låser, hendelser, forhold og semaforer i asyncio fungerer som deres konvensjonelle Python-kolleger.

En ting å huske på om alle disse metodene er at de erikke trådsikker. Dette er ikke et problem for asynkroniseringsoppgaver som kjøres i samme hendelsessløyfe. Men hvis du prøver å dele informasjon med oppgaver i en annen hendelsessløyfe, OS-tråd eller prosess, må du brukegjenging modulen og dens objekter for å gjøre det.

Videre, hvis du villansering coroutines over trådgrenser, brukasyncio.run_coroutine_threadsafe () funksjon, og pass hendelsessløyfen for å bruke den som parameter.

Sett en coroutine på pause i Python

En annen vanlig bruk avasyncio, og en underdiskutert, venter på en vilkårlig tid inne i en coroutine. Du kan ikke bruketime.sleep () for dette, ellers blokkerer du hele programmet. Bruk i stedetasyncio.sleep (), som gjør at andre coroutines kan fortsette å løpe.

Bruk asynkronisering på lavere nivå i Python

Til slutt, hvis du tror at appen du bygger kan kreve asyncioKomponenter på lavere nivå, ta en titt rundt før du begynner å kode: Det er stor sjanse for at noen allerede har bygget et asynkronisert Python-bibliotek som gjør det du trenger.

For eksempel, hvis du trenger asynkronisering av DNS-spørring, sjekkaiodns bibliotek, og for asynkroniserte SSH-økter, er detasyncSSH. Søk i PyPI etter nøkkelordet “async” (pluss andre oppgaverelaterte nøkkelord), eller sjekk den håndkurerte Awesome Asyncio-listen for ideer.

$config[zx-auto] not found$config[zx-overlay] not found