C++-korutiiniesimerkkejä

C Korutiiniesimerkkeja



Korutiinit tarjoavat kieliominaisuuden, jonka avulla voit kirjoittaa asynkronisen koodin organisoidummin ja lineaarisemmin, mikä edistää jäsenneltyä ja peräkkäistä lähestymistapaa. Ne tarjoavat mekanismin, jolla funktion suorittaminen keskeytetään ja käynnistetään uudelleen tietyissä tapauksissa pysäyttämättä koko säiettä. Korutiinit ovat hyödyllisiä käsiteltäessä tehtäviä, jotka edellyttävät I/O-toimintojen odottamista, kuten tiedostosta lukemista tai verkkopuhelun lähettämistä.

Korutiinit perustuvat generaattoreiden konseptiin, jossa funktio voi tuottaa arvoja ja myöhemmin jatkaa sen suorittamista. Korutiinit tarjoavat tehokkaan työkalun asynkronisten toimintojen hallitsemiseen ja voivat parantaa huomattavasti koodisi yleistä laatua.

Korutiinien käyttötarkoitukset

Korutiineja tarvitaan useista syistä nykyaikaisessa ohjelmoinnissa, erityisesti kielissä, kuten C++. Tässä on joitain keskeisiä syitä, miksi korutiinit ovat hyödyllisiä:







Korutiinit tarjoavat tyylikkään ratkaisun asynkroniseen ohjelmointiin. Niiden avulla on mahdollista luoda peräkkäiseltä ja estävältä näyttävä koodi, joka on yksinkertaisempi perustella ja ymmärtää. Korutiinit voivat keskeyttää niiden suorittamisen tietyissä kohdissa tukkimatta säikeitä, mikä mahdollistaa muiden tehtävien rinnakkaistoiminnan. Tämän ansiosta järjestelmän resursseja voidaan käyttää tehokkaammin ja reagointikykyä kasvaa sovelluksissa, jotka sisältävät I/O-toimintoja tai odottavat ulkoisia tapahtumia.



Ne saattavat helpottaa koodin ymmärtämistä ja ylläpitoa. Poistamalla monimutkaiset takaisinsoittoketjut tai tilakoneet, korutiinit mahdollistavat koodin kirjoittamisen lineaarisemmalla ja peräkkäisemmällä tyylillä. Tämä parantaa koodin organisointia, vähentää sisäkkäisyyttä ja tekee logiikasta helposti ymmärrettävän.



Korutiinit tarjoavat jäsennellyn tavan käsitellä samanaikaisuutta ja rinnakkaisuutta. Niiden avulla voit ilmaista monimutkaisia ​​koordinaatiomalleja ja asynkronisia työnkulkuja käyttämällä intuitiivisempaa syntaksia. Toisin kuin perinteisissä ketjutusmalleissa, joissa säikeet voivat olla tukossa, korutiinit voivat vapauttaa järjestelmäresursseja ja mahdollistaa tehokkaan moniajon.





Luodaan joitain esimerkkejä korutiinien toteutuksen havainnollistamiseksi C++:ssa.

Esimerkki 1: Peruskorutiinit

Peruskorutiiniesimerkki on esitetty seuraavassa:



#include

#sisällytä

struct Tämä Corout {

struct lupaus_tyyppi {

ThisCorout get_return_object ( ) { palata { } ; }

std :: suspend_never alkuperäinen_suspend ( ) { palata { } ; }

std :: suspend_never final_suspend ( ) ei paitsi { palata { } ; }

mitätön Käsittelemätön poikkeus ( ) { }

mitätön return_void ( ) { }

} ;

bool await_ready ( ) { palata väärä ; }

mitätön await_suspend ( std :: coroutine_handle <> h ) { }

mitätön odota_resume ( ) { std :: cout << 'Korotiini jatkuu.' << std :: endl ; }

} ;

Tämä Corout foo ( ) {

std :: cout << 'Korutiini on alkanut.' << std :: endl ;

co_await std :: keskeyttää_aina { } ;

co_return ;

}

int pää ( ) {

auto kr = foo ( ) ;

std :: cout << 'Korutiini on luotu.' << std :: endl ;

kr. odota_resume ( ) ;

std :: cout << 'Koritiini on valmis.' << std :: endl ;

palata 0 ;

}

Käydään läpi aiemmin toimitettu koodi ja selitetään se yksityiskohtaisesti:

Kun tarvittavat otsikkotiedostot on sisällytetty, määrittelemme 'ThisCorout'-rakenteen, joka edustaa korutiinia. 'ThisCorout' -kohdan sisällä on määritelty toinen rakenne, joka on 'promise_type', joka käsittelee korutiinilupauksen. Tämä rakenne tarjoaa erilaisia ​​toimintoja, joita korutiinikoneisto vaatii.

Hakasulkeissa käytämme get_return_object()-funktiota. Se palauttaa itse korutiiniobjektin. Tässä tapauksessa se palauttaa tyhjän 'ThisCorout'-objektin. Tämän jälkeen kutsutaan inicial_suspend()-funktio, joka määrittää käyttäytymisen, kun korutiini käynnistetään ensimmäisen kerran. Std::suspend_never tarkoittaa, että korutiinia ei pidä keskeyttää aluksi.

Sen jälkeen meillä on final_suspend()-funktio, joka määrittää käyttäytymisen, kun korutiini on päättymässä. Std::suspend_never tarkoittaa, että korutiinia ei pidä keskeyttää ennen sen viimeistelyä.

Jos korutiini heittää poikkeuksen, unhandled_exception() -metodi vedetään. Tässä esimerkissä se on tyhjä funktio, mutta voit käsitellä poikkeuksia tarpeen mukaan. Kun korutiini päättyy antamatta arvoa, paluu_void() -menetelmä vedetään. Tässä tapauksessa se on myös tyhjä toiminto.

Määrittelemme myös kolme jäsentoimintoa “ThisCoroutissa”. await_ready()-funktiota kutsutaan tarkistamaan, onko korutiini valmis jatkamaan suoritusta. Tässä esimerkissä se palauttaa aina false, mikä osoittaa, että korutiini ei ole valmis jatkamaan välittömästi. Kun korutiini keskeytetään, kutsutaan menetelmä await_suspend(). Tässä se on tyhjä toiminto, mikä tarkoittaa, että jousitusta ei tarvita. Ohjelma kutsuu await_resume()-funktiota, kun korutiinia jatketaan keskeytyksen jälkeen. Se vain tulostaa viestin, joka ilmoittaa, että korutiini on jatkunut.

Seuraavat koodin rivit määrittelevät foo()-korutiinifunktion. Foo():n sisällä aloitamme tulostamalla viestin, joka ilmoittaa, että korutiini on alkanut. Sitten co_await std::suspend_always{} käytetään keskeyttämään korutiini, ja se osoittaa, että sitä voidaan jatkaa myöhemmin. co_return-lausetta käytetään korutiinin lopettamiseen palauttamatta mitään arvoa.

Main()-funktiossa rakennamme objektin 'cr' tyyppiä 'ThisCorout' kutsumalla foo(). Tämä luo ja käynnistää korutiinin. Sitten tulostetaan viesti, joka ilmoittaa, että korutiini on luotu. Seuraavaksi kutsumme 'cr'-korutiiniobjektin await_resume()-funktiota jatkaaksemme sen suorittamista. await_resume() -kenttään tulostetaan 'Korutiini jatkuu' -viesti. Lopuksi näytämme viestin, joka ilmoittaa, että korjaus on valmis ennen ohjelman päättymistä.

Kun suoritat tämän ohjelman, tulos on seuraava:

Esimerkki 2: Korutiini parametrien ja tuoton kanssa

Nyt tätä esimerkkiä varten tarjoamme koodin, joka osoittaa korutiinien käytön parametreilla ja myötävaikutuksella C++:ssa luomaan generaattorin kaltainen käyttäytyminen numerosarjan tuottamiseksi.

#include

#sisällytä

#sisällytä

struct UUSI Korutiini {

struct p_tyyppi {

std :: vektori < int > arvot ;

NEWCoroutine get_return_object ( ) { palata { } ; }

std :: keskeyttää_aina alkuperäinen_suspend ( ) { palata { } ; }

std :: keskeyttää_aina final_suspend ( ) ei paitsi { palata { } ; }

mitätön Käsittelemätön poikkeus ( ) { }

mitätön return_void ( ) { }

std :: keskeyttää_aina tuotto_arvo ( int arvo ) {

arvot. työnnä takaisin ( arvo ) ;

palata { } ;

}

} ;

std :: vektori < int > arvot ;

struct iteraattori {

std :: coroutine_handle <> chorus_handle ;

bool-operaattori != ( konst iteraattori & muu ) konst { palata chorus_handle != muu. chorus_handle ; }

iteraattori & operaattori ++ ( ) { chorus_handle. jatkaa ( ) ; palata * Tämä ; }

int operaattori * ( ) konst { palata chorus_handle. lupaus ( ) . arvot [ 0 ] ; }

} ;

iteraattori alkaa ( ) { palata iteraattori { std :: coroutine_handle < p_tyyppi >:: from_promise ( lupaus ( ) ) } ; }

iteraattorin loppu ( ) { palata iteraattori { nullptr } ; }

std :: coroutine_handle < p_tyyppi > lupaus ( ) { palata
std :: coroutine_handle < p_tyyppi >:: from_promise ( * Tämä ) ; }

} ;

NEWCoroutine generoi numeroita ( ) {

yhteistuotto 5 ;

yhteistuotto 6 ;

yhteistuotto 7 ;

}

int pää ( ) {

NEWCoroutine nc = generoiNummeroita ( ) ;

varten ( int arvo : nc ) {

std :: cout << arvo << ' ' ;

}

std :: cout << std :: endl ;

palata 0 ;

}

Edellisessä koodissa NEWCoroutine-rakenne edustaa korutiinipohjaista generaattoria. Se sisältää sisäkkäisen 'p_type'-rakenteen, joka toimii korutiinin lupaustyyppinä. Rakenne p_type määrittelee korutiinikoneiston vaatimat funktiot, kuten get_return_object(), origin_suspend(), final_suspend(), unhandled_exception() ja return_void(). Rakenne p_type sisältää myös tuottoarvon(int arvo) -funktion, jota käytetään tuottamaan arvot korutiinista. Se lisää annetun arvon arvovektoriin.

NEWCoroutine-rakenne sisältää std::vector -jäsenmuuttujan nimeltä 'arvot', joka edustaa luotuja arvoja. NEWCoroutinen sisällä on sisäkkäinen rakenneiteraattori, jonka avulla voidaan iteroida luotujen arvojen yli. Siinä on coro_handle, joka on korutiinin kahva ja se määrittelee operaattorit, kuten !=, ++ ja * iteraatiota varten.

Käytämme begin()-funktiota iteraattorin luomiseen korutiinin alkuun hankkimalla coro_handle p_type-lupauksesta. Kun taas end()-funktio luo iteraattorin, joka edustaa korutiinin loppua ja on rakennettu nullptr coro_handle -funktiolla. Sen jälkeen lupaus()-funktiota käytetään palauttamaan lupaustyyppi luomalla coroutine_handle p_type-lupauksesta. GenenerNumbers()-funktio on korutiini, joka tuottaa kolme arvoa – 5, 6 ja 7 – käyttämällä co_yield-avainsanaa.

Main()-funktiossa NEWCoroutine-esiintymä nimeltä 'nc' luodaan kutsumalla generoNumbers()-korutiini. Tämä alustaa korutiinin ja tallentaa sen tilan. Aluepohjaista 'for'-silmukkaa käytetään iteroimaan 'nc'-arvot, ja jokainen arvo tulostetaan, jotka erotetaan välilyönnillä käyttämällä std::cout.

Luotu tulos on seuraava:

Johtopäätös

Tämä artikkeli osoittaa korutiinien käytön C++:ssa. Keskustelimme kahdesta esimerkistä. Ensimmäisessä kuvassa peruskorutiini luodaan C++-ohjelmassa käyttämällä korutiinifunktioita. Kun taas toinen demonstraatio suoritettiin käyttämällä korutiineja parametrien kanssa ja antamalla periksi generaattorin kaltaisen käyttäytymisen luomiseksi numerosarjan luomiseksi.