Primeri korutin C++

Primeri Korutin C



Korutine zagotavljajo jezikovno funkcijo, ki vam omogoča pisanje asinhrone kode na bolj organiziran in linearen način ter spodbuja strukturiran in zaporedni pristop. Omogočajo mehanizem za zaustavitev in ponovni zagon izvajanja funkcije v določenih primerih, ne da bi ustavili celotno nit. Korutine so v pomoč pri obravnavanju nalog, ki zahtevajo čakanje na V/I operacije, kot je branje iz datoteke ali pošiljanje omrežnega klica.

Korutine temeljijo na konceptu generatorjev, kjer lahko funkcija vrne vrednosti in se pozneje nadaljuje z izvajanjem. Korutine zagotavljajo zmogljivo orodje za upravljanje asinhronih operacij in lahko močno izboljšajo splošno kakovost vaše kode.

Uporaba korutin

Korutine so v sodobnem programiranju potrebne iz več razlogov, zlasti v jezikih, kot je C++. Tukaj je nekaj ključnih razlogov, zakaj so korutine koristne:







Korutine nudijo elegantno rešitev za asinhrono programiranje. Omogočajo ustvarjanje kode, ki je videti zaporedna in blokirajoča, kar je preprostejše za sklepanje in razumevanje. Korutine lahko prekinejo svoje izvajanje na določenih točkah, ne da bi blokirale niti, kar omogoča vzporedno delovanje drugih nalog. Zaradi tega se lahko sistemski viri uporabljajo učinkoviteje, odzivnost pa se poveča v aplikacijah, ki vključujejo V/I operacije ali čakanje na zunanje dogodke.



Lahko olajšajo razumevanje in vzdrževanje kode. Z odpravo zapletenih verig povratnih klicev ali državnih avtomatov korutine omogočajo pisanje kode v bolj linearnem in zaporednem slogu. To izboljša organizacijo kode, zmanjša gnezdenje in olajša razumevanje logike.



Korutine zagotavljajo strukturiran način za obravnavanje sočasnosti in vzporednosti. Omogočajo vam izražanje zapletenih koordinacijskih vzorcev in asinhronih delovnih tokov z uporabo bolj intuitivne sintakse. Za razliko od tradicionalnih modelov niti, kjer so niti morda blokirane, lahko korutine sprostijo sistemske vire in omogočijo učinkovito večopravilnost.





Ustvarimo nekaj primerov za prikaz izvajanja korutin v C++.

Primer 1: Osnovne korutine

Osnovni primer korutin je naveden v naslednjem:



#include

#include

struct ThisCorout {

struct vrsta_obljube {

ThisCorout get_return_object ( ) { vrnitev { } ; }

std :: suspend_never začetna_prekinitev ( ) { vrnitev { } ; }

std :: suspend_never final_suspend ( ) noexcept { vrnitev { } ; }

praznina neobdelana_izjema ( ) { }

praznina return_void ( ) { }

} ;

bool await_ready ( ) { vrnitev lažno ; }

praznina await_suspend ( std :: ročaj_korutine <> h ) { }

praznina await_resume ( ) { std :: cout << 'Coroutine se nadaljuje.' << std :: konec ; }

} ;

Ta Corout foo ( ) {

std :: cout << 'Korutina se je začela.' << std :: konec ;

co_await std :: suspend_always { } ;

co_return ;

}

int glavni ( ) {

avto kr = foo ( ) ;

std :: cout << 'Korutina je ustvarjena.' << std :: konec ;

kr. await_resume ( ) ;

std :: cout << 'Korutina je končana.' << std :: konec ;

vrnitev 0 ;

}

Oglejmo si prej navedeno kodo in jo podrobno razložimo:

Ko vključimo zahtevane datoteke glave, definiramo strukturo »ThisCorout«, ki predstavlja sorutino. Znotraj »ThisCorout« je definirana druga struktura, ki je »promise_type« in obravnava obljubo sorutine. Ta struktura nudi različne funkcije, ki jih zahteva soprogramski stroj.

Znotraj oklepajev uporabljamo funkcijo get_return_object(). Vrne sam predmet korutine. V tem primeru vrne prazen objekt »ThisCorout«. Nato se prikliče funkcija initial_suspend(), ki določi vedenje ob prvem zagonu korutine. Std::suspend_never pomeni, da soprogram ne sme biti prvotno začasno ustavljen.

Po tem imamo funkcijo final_suspend(), ki določa vedenje, ko se korutina konča. Std::suspend_never pomeni, da korutina ne sme biti začasno ustavljena pred dokončanjem.

Če koprogram vrže izjemo, se prikliče metoda unhandled_exception(). V tem primeru je to prazna funkcija, vendar lahko po potrebi obravnavate izjeme. Ko se soprogram konča brez vrnitve vrednosti, se prikliče metoda return_void(). V tem primeru je tudi prazna funkcija.

Definiramo tudi tri članske funkcije znotraj »ThisCorout«. Funkcija await_ready() se pokliče, da preveri, ali je koprogram pripravljen za nadaljevanje izvajanja. V tem primeru vedno vrne false, kar pomeni, da sorutina ni pripravljena za takojšnje nadaljevanje. Ko bo soprogram začasno ustavljen, se pokliče metoda await_suspend(). Tukaj je prazna funkcija, kar pomeni, da prekinitev ni potrebna. Program pokliče await_resume(), ko se sorutina nadaljuje po prekinitvi. Izpiše samo sporočilo, ki navaja, da je bila sorutina nastavljena.

Naslednje vrstice kode definirajo soprogram foo(). Znotraj foo() začnemo s tiskanjem sporočila, ki navaja, da se je sorutina začela. Nato se co_await std::suspend_always{} uporabi za prekinitev sorutine in nakazuje, da jo je mogoče nadaljevati pozneje. Stavek co_return se uporablja za dokončanje soprograma brez vrnitve vrednosti.

V funkciji main() sestavimo objekt 'cr' tipa 'ThisCorout' s klicem foo(). To ustvari in zažene sorutino. Nato se natisne sporočilo, ki navaja, da je bila sorutina ustvarjena. Nato pokličemo await_resume() na objektu koprograma 'cr', da nadaljujemo z njegovim izvajanjem. Znotraj await_resume() je natisnjeno sporočilo »Korutina se nadaljuje«. Na koncu prikažemo sporočilo, ki navaja, da je korutina končana, preden se program zaključi.

Ko zaženete ta program, je rezultat naslednji:

Primer 2: Korutina s parametri in donosom

Zdaj za to ilustracijo nudimo kodo, ki prikazuje uporabo korutin s parametri in donosom v C++ za ustvarjanje vedenja, podobnega generatorju, za ustvarjanje zaporedja števil.

#include

#include

#include

struct NOVAKorutina {

struct p_vrsta {

std :: vektor < int > vrednote ;

NOVAKorutina get_return_object ( ) { vrnitev { } ; }

std :: suspend_always začetna_prekinitev ( ) { vrnitev { } ; }

std :: suspend_always final_suspend ( ) noexcept { vrnitev { } ; }

praznina neobdelana_izjema ( ) { }

praznina return_void ( ) { }

std :: suspend_always vrednost_donosa ( int vrednost ) {

vrednote. porini nazaj ( vrednost ) ;

vrnitev { } ;

}

} ;

std :: vektor < int > vrednote ;

struct iterator {

std :: ročaj_korutine <> chorus_handle ;

bool operator != ( konst iterator & drugo ) konst { vrnitev chorus_handle != drugo. chorus_handle ; }

iterator & operater ++ ( ) { chorus_handle. Nadaljuj ( ) ; vrnitev * to ; }

int operater * ( ) konst { vrnitev chorus_handle. obljuba ( ) . vrednote [ 0 ] ; }

} ;

iterator začeti ( ) { vrnitev iterator { std :: ročaj_korutine < p_vrsta >:: from_promise ( obljuba ( ) ) } ; }

konec iteratorja ( ) { vrnitev iterator { nullptr } ; }

std :: ročaj_korutine < p_vrsta > obljuba ( ) { vrnitev
std :: ročaj_korutine < p_vrsta >:: from_promise ( * to ) ; }

} ;

NOVOCorutine generateNumbers ( ) {

so_dobitek 5 ;

so_dobitek 6 ;

so_dobitek 7 ;

}

int glavni ( ) {

NOVOCorutine nc = generirajŠtevilke ( ) ;

za ( int vrednost : nc ) {

std :: cout << vrednost << ' ' ;

}

std :: cout << std :: konec ;

vrnitev 0 ;

}

V prejšnji kodi predstavlja struktura NEWCoroutine generator, ki temelji na soprogramu. Vsebuje ugnezdeno strukturo »p_type«, ki služi kot tip obljube za koprogram. Struktura p_type opredeljuje funkcije, ki jih zahteva soprogramski stroj, kot so get_return_object(), initial_suspend(), final_suspend(), unhandled_exception() in return_void(). Struktura p_type vključuje tudi funkcijo yield_value(int value), ki se uporablja za pridobivanje vrednosti iz soprograma. Podano vrednost doda vektorju vrednosti.

Struktura NEWCoroutine vključuje spremenljivko člana std::vector , imenovano »vrednosti«, ki predstavlja ustvarjene vrednosti. Znotraj NEWCoroutine je ugnezdeni iterator strukture, ki omogoča ponavljanje ustvarjenih vrednosti. Vsebuje coro_handle, ki je ročaj za soprogram in definira operatorje, kot so !=, ++ in * za iteracijo.

Funkcijo begin() uporabljamo za ustvarjanje iteratorja na začetku soprograma, tako da pridobimo coro_handle iz obljube p_type. Medtem ko funkcija end() ustvari iterator, ki predstavlja konec korutine in je sestavljen z nullptr coro_handle. Po tem se funkcija promise() uporabi za vrnitev vrste obljube z ustvarjanjem coroutine_handle iz obljube p_type. Funkcija generateNumbers() je korutina, ki vrne tri vrednosti – 5, 6 in 7 – z uporabo ključne besede co_yield.

V funkciji main() je primerek NEWCoroutine z imenom 'nc' ustvarjen s priklicem soprograma generateNumbers(). To inicializira korutino in zajame njeno stanje. Za ponavljanje vrednosti »nc« se uporablja zanka »for«, ki temelji na obsegu, in vsaka vrednost je natisnjena, ki je ločena s presledkom z uporabo std::cout.

Ustvarjeni izhod je naslednji:

Zaključek

Ta članek prikazuje uporabo korutin v C++. Razpravljali smo o dveh primerih. Za prvo ilustracijo je osnovna korutina ustvarjena v programu C++ z uporabo funkcij korutine. Medtem ko je bila druga predstavitev izvedena z uporabo korutin s parametri in popuščanjem za ustvarjanje vedenja, podobnega generatorju, za ustvarjanje zaporedja številk.