Coroutines er i utgangspunktet funksjoner hvis utførelse kan pause / suspenderes på et bestemt punkt, og da kan vi gjenoppta utførelsen fra det samme punktet senere når vi vil.

Vi trenger en mekanisme-eller for å være mer presis, et søkeord-som vi kan sette inn et kontrollpunkt og fortelle programmet at vi vil pause utførelsen av funksjonen her og returnere kontrollen til det punktet den ringte fra. Vi gjenopptar henrettelsen når vi vil.

I Python kan vi pause utførelsen av en funksjon ved hjelp av nøkkelordet yield.

så her er hvor ting blir interessante:

  • vi kan tenke på en coroutine som en funksjon som har ett eller flere kontrollpunkter hvor utførelsen vil bli pauset og kontrollen vil bli returnert til det punktet der den ble kalt fra.
  • i hovedsak er en coroutine en funksjon delt inn i mange deler, og vi kan utføre hver del av en coroutine når vi utfører hver iterasjon av a for loop ved hjelp av funksjonen next.

her er et grunnleggende eksempel:

OUTPUT :<class 'generator'>
Function Starts
Function Ends

Fra utgangen merker vi noen ting:

  • først må vi ringe coroutine / funksjonen som vil gi oss et generatorobjekt.
  • det generatorobjektet vil oppføre seg på samme måte som en iterator, men i tilfelle av en iterator, krysser vi over en iterbar. Med en generator utfører vi deler av coroutinen.
  • Akkurat som et StopIteration unntak blir kastet og fanget bak kulissene til a for loop, skjer det samme i dette tilfellet når den siste delen av coroutinen utføres.

nå er denne pause av funksjonen i mellom veldig interessant og åpner opp noen muligheter:

  • når funksjonen er pauset, gjør vi ingenting, noe som er tilfelle vi nettopp så.
  • Anta at en variabel blir endret flere ganger i en funksjon, og vi vil ha verdien av den aktuelle variabelen ved et bestemt kontrollpunkt. Så når vi pause den funksjonen på det aktuelle kontrollpunktet, returnerer den verdien av den variabelen.

la oss se et eksempel:

OUTPUT :Function Part 1
5
Function part 2
12
Function part 3

her returneres verdien av x med yield ved forskjellige kontrollpunkter, da funksjonsutførelsen er satt på pause.

Når vi utfører den siste delen av funksjonen, og det ikke er noe utbytte igjen i funksjonen, etter å ha utført den siste delen, vil et StopIteration unntak bli hevet.

Mye som når en iterator prøver å utføre neste funksjon, men det er ikke flere elementer igjen i iterable, øker det også StopIteration unntaket.

  • Anta at vi vil sende en verdi (som kan være en konstant eller variabel) ved et bestemt kontrollpunkt (dvs.ved en bestemt tilstand av en funksjon). Vi kan også gjøre det ved hjelp av yield søkeordet. Når vi vil sende en verdi, bruker vi funksjonen send i stedet for next.

la oss se et eksempel:

OUTPUT :Function part 1
6
Function part 2
12
Function part 3

grunnen til at vi brukte next før vi brukte send er at vi bare kan bruke send når vi er på yield kontrollpunktet, og yield er på høyre side av uttrykket. Så for å nå den første yield må vi bruke next – funksjonen.

Nå kommer her en interessant anvendelse av coroutines. Anta at vi vil bytte frem og tilbake mellom to funksjoner som vi gjør i multithreading. I multithreading, til en interrupt oppstår AV OPERATIVSYSTEMET, vil den fortsette å utføre. I dette tilfellet kan vi bytte når vi vil.

la oss se et eksempel:

OUTPUT :Function 1 part 1
Function 2 part 1
Function 1 part 2
Function 1 part 3
Function 2 part 2
Function 2 part 3
Function 2 part 4
Function 1 part 4
Function 1 part 5

I dette eksemplet kan vi se at vi kan bytte frem og tilbake mellom coroutines når vi vil.

Så hvis vi skriver vår egen tilpassede planlegger som håndterer bytte mellom flere coroutines, kan vi oppnå med single threading hva vi gjør med multithreading.

Coroutiner har mange applikasjoner som samtidighet og andre programmeringsmønstre kan også implementeres, Som Produsent-Forbruker eller Avsender-Mottaker i nettverksprogrammering. Jeg skal utforske dem i kommende artikler.

Coroutines er også byggesteinene i mange rammer som asyncio, twisted, aiohttp. De kan også lenkes sammen for å lage rørledninger og løse problemer.