C++ Coroutines pavyzdžiai

C Coroutines Pavyzdziai



Korutinės suteikia kalbos funkciją, leidžiančią rašyti asinchroninį kodą labiau organizuotu ir linijiniu būdu, skatinant struktūrinį ir nuoseklų požiūrį. Jie suteikia mechanizmą, leidžiantį pristabdyti ir iš naujo paleisti funkcijos vykdymą tam tikrais atvejais, nestabdant visos gijos. Korutina yra naudinga atliekant užduotis, kurioms reikia laukti įvesties / išvesties operacijų, pvz., nuskaityti iš failo arba išsiųsti tinklo skambutį.

Korutinos yra pagrįstos generatorių koncepcija, kai funkcija gali duoti reikšmes ir vėliau ją atnaujinti, kad būtų galima tęsti vykdymą. Korutinės yra galingas įrankis asinchroninėms operacijoms valdyti ir gali labai pagerinti bendrą kodo kokybę.

Korutinos naudojimas

Korutinos reikalingos dėl kelių priežasčių šiuolaikiniame programavime, ypač tokiomis kalbomis kaip C++. Štai keletas pagrindinių priežasčių, kodėl rutina yra naudinga:







Korutinos yra elegantiškas asinchroninio programavimo sprendimas. Jie leidžia sukurti kodą, kuris atrodo nuoseklus ir blokuoja, kurį lengviau samprotauti ir suprasti. Korutinos gali sustabdyti jų vykdymą tam tikruose taškuose, neužblokuodamos gijų, taip leidžiant lygiagrečiai atlikti kitas užduotis. Dėl šios priežasties sistemos ištekliai gali būti naudojami efektyviau, o programose, kuriose atliekamos įvesties/išvesties operacijos arba laukiama išorinių įvykių, padidėja reagavimas.



Jie gali padėti lengviau suprasti ir prižiūrėti kodą. Pašalinus sudėtingas atgalinio ryšio grandines arba būsenos mašinas, korutinos leidžia kodą rašyti linijiškesniu ir nuoseklesniu stiliumi. Tai pagerina kodo organizavimą, sumažina įdėjimą ir leidžia lengvai suprasti logiką.



Korutinos suteikia struktūrinį būdą tvarkyti lygiagretumą ir lygiagretumą. Jie leidžia išreikšti sudėtingus koordinavimo modelius ir asinchronines darbo eigas naudojant intuityvesnę sintaksę. Skirtingai nuo tradicinių gijų kūrimo modelių, kuriuose gijos gali būti užblokuotos, korutina gali atlaisvinti sistemos išteklius ir įgalinti efektyvų kelių užduočių atlikimą.





Sukurkime kelis pavyzdžius, kad parodytume korutinų įgyvendinimą C++.

1 pavyzdys: pagrindinės korutinos

Pagrindinis korutinos pavyzdys pateikiamas toliau:



#include

#include

struktūra Šis Corout {

struktūra pažado_tipas {

ThisCorout get_return_object ( ) { grąžinti { } ; }

std :: sustabdyti_niekada pradinis_sustabdymas ( ) { grąžinti { } ; }

std :: sustabdyti_niekada final_suspend ( ) neišskyrus { grąžinti { } ; }

tuštuma neapdorota_išimtis ( ) { }

tuštuma return_void ( ) { }

} ;

bool await_ready ( ) { grąžinti klaidinga ; }

tuštuma laukti_sustabdyti ( std :: coroutine_handle <> h ) { }

tuštuma laukti_gyvenimo ( ) { std :: cout << „Korutina atnaujinta“. << std :: endl ; }

} ;

This Corout foo ( ) {

std :: cout << „Korutina prasidėjo“. << std :: endl ;

co_await std :: sustabdyti_visada { } ;

co_return ;

}

tarpt pagrindinis ( ) {

automatinis kr = foo ( ) ;

std :: cout << „Korutina sukurta“. << std :: endl ;

kr. laukti_gyvenimo ( ) ;

std :: cout << „Korutina baigta“. << std :: endl ;

grąžinti 0 ;

}

Panagrinėkime anksčiau pateiktą kodą ir paaiškinkime jį išsamiai:

Įtraukę reikalingus antraštės failus, apibrėžiame „ThisCorout“ struktūrą, kuri reiškia korotiną. „ThisCorout“ viduje yra apibrėžta kita struktūra, kuri yra „promise_type“, kuri tvarko korutinos pažadą. Ši struktūra teikia įvairias funkcijas, kurių reikalauja korutinos mechanizmai.

Skliausteliuose naudojame funkciją get_return_object(). Jis grąžina patį korutinos objektą. Šiuo atveju jis grąžina tuščią objektą „ThisCorout“. Tada iškviečiama inicialinio_suspend() funkcija, kuri nustato elgesį, kai pirmą kartą paleidžiama korutina. std::suspend_never reiškia, kad korutina iš pradžių neturėtų būti sustabdyta.

Po to turime funkciją final_suspend(), kuri nustato elgseną, kai baigsis korutina. std::suspend_never reiškia, kad korutina neturėtų būti sustabdyta prieš jos užbaigimą.

Jei korutina pateikia išimtį, iškviečiamas unhandled_exception() metodas. Šiame pavyzdyje tai tuščia funkcija, bet prireikus galite tvarkyti išimtis. Kai korutina baigiasi nesuteikdama reikšmės, iškviečiamas return_void() metodas. Šiuo atveju tai taip pat tuščia funkcija.

Taip pat „ThisCorout“ apibrėžiame tris narių funkcijas. Funkcija await_ready() iškviečiama patikrinti, ar korutina yra pasirengusi tęsti vykdymą. Šiame pavyzdyje jis visada grąžina false, o tai rodo, kad korutina nėra paruošta nedelsiant atnaujinti. Kai korutina bus sustabdyta, iškviečiamas metodas await_suspend(). Čia tai tuščia funkcija, o tai reiškia, kad sustabdyti nereikia. Programa iškviečia await_resume(), kai korutina atnaujinama po sustabdymo. Tai tiesiog išveda pranešimą, kuriame teigiama, kad korutina buvo atnaujinta.

Kitos kodo eilutės apibrėžia foo() korutinos funkciją. Viduje foo () pradedame spausdindami pranešimą, kuriame teigiama, kad korutina prasidėjo. Tada co_await std::suspend_always{} naudojamas norint sustabdyti patikrinimą ir nurodo, kad ją bus galima atnaujinti vėliau. Teiginys co_return naudojamas užbaigti korutą negrąžinant jokios reikšmės.

Funkcijoje main() mes sukuriame objektą „cr“, kurio tipas yra „ThisCorout“, iškviesdami foo (). Taip sukuriama ir pradedama koruna. Tada išspausdinamas pranešimas, kad korutina buvo sukurta. Tada iškviečiame await_resume() korutinos objekte „cr“, kad atnaujintume jo vykdymą. Lauke await_resume () atspausdinamas pranešimas „Korutina atnaujinta“. Galiausiai rodome pranešimą, kuriame teigiama, kad tikrinimas baigtas prieš pasibaigiant programai.

Kai paleidžiate šią programą, išvestis yra tokia:

2 pavyzdys: Korutina su parametrais ir derlingumu

Dabar šiai iliustracijai pateikiame kodą, kuris parodo, kaip naudojamos korutinos su parametrais ir pasiduoda C++, kad būtų sukurtas į generatorių panašus elgesys, sukuriantis skaičių seką.

#include

#include

#įtraukti

struktūra NAUJIENAKorutina {

struktūra p_type {

std :: vektorius < tarpt > vertybes ;

NEWCoroutine get_return_object ( ) { grąžinti { } ; }

std :: sustabdyti_visada pradinis_sustabdymas ( ) { grąžinti { } ; }

std :: sustabdyti_visada final_suspend ( ) neišskyrus { grąžinti { } ; }

tuštuma neapdorota_išimtis ( ) { }

tuštuma return_void ( ) { }

std :: sustabdyti_visada derliaus_vertė ( tarpt vertė ) {

vertybes. pastumti atgal ( vertė ) ;

grąžinti { } ;

}

} ;

std :: vektorius < tarpt > vertybes ;

struktūra iteratorius {

std :: coroutine_handle <> choras_rankena ;

bool operatorius != ( konst iteratorius & kitas ) konst { grąžinti chorus_rankena != kitas. choras_rankena ; }

iteratorius & operatorius ++ ( ) { choras_rankena. Aprašymas ( ) ; grąžinti * tai ; }

tarpt operatorius * ( ) konst { grąžinti choras_rankena. pažadas ( ) . vertybes [ 0 ] ; }

} ;

paleisti iteratorių ( ) { grąžinti iteratorius { std :: coroutine_handle < p_tipas >:: from_promise ( pažadas ( ) ) } ; }

iteratoriaus pabaiga ( ) { grąžinti iteratorius { nullptr } ; }

std :: coroutine_handle < p_type > pažadas ( ) { grąžinti
std :: coroutine_handle < p_type >:: from_promise ( * tai ) ; }

} ;

NEWCoroutine generuoja skaičius ( ) {

bendras derlius 5 ;

bendras derlius 6 ;

bendras derlius 7 ;

}

tarpt pagrindinis ( ) {

NEWCoroutine nc = generuotiSkaičius ( ) ;

dėl ( tarpt vertė : nc ) {

std :: cout << vertė << ' ' ;

}

std :: cout << std :: endl ;

grąžinti 0 ;

}

Ankstesniame kode NEWCoroutine struktūra yra korutinos pagrindu sukurtas generatorius. Jame yra įdėta „p_type“ struktūra, kuri naudojama kaip korutinos pažado tipas. Struktūra p_type apibrėžia funkcijas, kurių reikalauja korutinos mechanizmai, pvz., get_return_object(), inicialus_suspend(), final_suspend(), unhandled_exception() ir return_void(). Struktūra p_type taip pat apima funkciją return_value(int value), kuri naudojama norint gauti reikšmes iš korutinos. Jis prideda pateiktą vertę prie verčių vektoriaus.

NEWCoroutine struktūra apima std::vector nario kintamąjį, vadinamą 'vertėmis', kuris atspindi sugeneruotas reikšmes. NEWCoroutine viduje yra įdėtas struktūrų iteratorius, leidžiantis kartoti sugeneruotas reikšmes. Ji turi coro_handle, kuri yra korutinos rankena ir apibrėžia tokius operatorius kaip !=, ++ ir * iteracijai.

Naudojame funkciją begin() norėdami sukurti iteratorių korutinos pradžioje, gaudami coro_handle iš p_type pažado. Tuo tarpu funkcija end() sukuria iteratorių, kuris reiškia korutinos pabaigą ir yra sukonstruotas naudojant nullptr coro_handle. Po to funkcija pažadas() naudojama pažado tipui grąžinti sukuriant coroutine_handle iš p_type pažado. Funkcija generateNumbers() yra korutina, kuri duoda tris reikšmes – 5, 6 ir 7 – naudojant raktinį žodį co_yield.

Funkcijoje main() NEWCoroutine egzempliorius, pavadintas „nc“, sukuriamas iškviečiant generavimo numerių () korutiną. Tai inicijuoja koroną ir užfiksuoja jos būseną. Diapazonu pagrįsta kilpa „for“ naudojama kartoti „nc“ reikšmes, o kiekviena reikšmė spausdinama, kuri yra atskirta tarpu, naudojant std::cout.

Sugeneruota išvestis yra tokia:

Išvada

Šis straipsnis parodo korutinų panaudojimą C++. Mes aptarėme du pavyzdžius. Pirmajai iliustracijai pagrindinė korutina sukurta C++ programoje, naudojant korutinos funkcijas. Tuo tarpu antrasis demonstravimas buvo atliktas naudojant korutinas su parametrais ir leidžiant generuoti į generatorių panašų elgesį, kad būtų sukurta skaičių seka.