Primjeri C++ korutina

Primjeri C Korutina



Korutine pružaju jezičnu značajku koja vam omogućuje pisanje asinkronog koda na organiziraniji i linearniji način, promovirajući strukturirani i sekvencijalni pristup. Oni daju mehanizam za pauziranje i ponovno pokretanje izvršavanja funkcije u određenim slučajevima bez zaustavljanja cijele niti. Korutine su korisne pri rukovanju zadacima koji zahtijevaju čekanje I/O operacija kao što je čitanje iz datoteke ili slanje mrežnog poziva.

Korutine se temelje na konceptu generatora gdje funkcija može dati vrijednosti i kasnije se nastaviti za nastavak izvršenja. Korutine pružaju moćan alat za upravljanje asinkronim operacijama i mogu uvelike poboljšati ukupnu kvalitetu vašeg koda.

Upotreba korutina

Korutine su potrebne iz nekoliko razloga u modernom programiranju, posebice u jezicima poput C++. Evo nekoliko ključnih razloga zašto su korutine korisne:







Korutine pružaju elegantno rješenje za asinkrono programiranje. Omogućuju stvaranje koda koji se čini sekvencijalan i blokirajući koji je jednostavniji za razmišljanje i razumijevanje. Korutine mogu obustaviti svoje izvršenje na određenim točkama bez blokiranja niti, omogućujući paralelni rad drugih zadataka. Zbog toga se resursi sustava mogu koristiti učinkovitije, a odziv se povećava u aplikacijama koje uključuju I/O operacije ili čekanje na vanjske događaje.



Oni bi mogli olakšati razumijevanje i održavanje koda. Eliminirajući složene lance povratnih poziva ili automate stanja, korutine omogućuju pisanje koda u linearnijem i sekvencijalnijem stilu. To poboljšava organizaciju koda, smanjuje gniježđenje i čini logiku lakom za razumijevanje.



Korutine pružaju strukturiran način za rukovanje istovremenošću i paralelizmom. Omogućuju vam da izrazite složene obrasce koordinacije i asinkrone tijekove rada koristeći intuitivniju sintaksu. Za razliku od tradicionalnih modela niti gdje se niti mogu blokirati, korutine mogu osloboditi resurse sustava i omogućiti učinkovit multitasking.





Kreirajmo neke primjere da demonstriramo implementaciju korutina u C++.

Primjer 1: Osnovne korutine

Osnovni primjer korutina dan je u nastavku:



#include

#include

strukturirati ThisCorout {

strukturirati vrsta_obećanja {

ThisCorout get_return_object ( ) { povratak { } ; }

std :: suspend_never početna_obustava ( ) { povratak { } ; }

std :: suspend_never konačna_obustava ( ) noexcept { povratak { } ; }

poništiti neobrađena_iznimka ( ) { }

poništiti return_void ( ) { }

} ;

bool čekaj_spreman ( ) { povratak lažno ; }

poništiti čekaj_odgoditi ( std :: ručica_korutine <> h ) { }

poništiti čekaj_nastavi ( ) { std :: cout << 'Korutina je nastavljena.' << std :: endl ; }

} ;

Ovo je Corout foo ( ) {

std :: cout << 'Korutina je počela.' << std :: endl ;

co_ekaj std :: suspend_uvijek { } ;

su_povratak ;

}

int glavni ( ) {

auto kr = fuj ( ) ;

std :: cout << 'Korutina je stvorena.' << std :: endl ;

kr. čekaj_nastavi ( ) ;

std :: cout << 'Korutina završena.' << std :: endl ;

povratak 0 ;

}

Prođimo kroz prethodno navedeni kod i detaljno ga objasnimo:

Nakon uključivanja potrebnih datoteka zaglavlja, definiramo strukturu 'ThisCorout' koja predstavlja korutinu. Unutar 'ThisCorout', definirana je druga struktura koja je 'promise_type' koja obrađuje obećanje korutine. Ova struktura pruža razne funkcije koje su potrebne korutinskom stroju.

Unutar zagrada koristimo funkciju get_return_object(). Vraća sam objekt korutine. U ovom slučaju, vraća prazan objekt 'ThisCorout'. Zatim se poziva funkcija initial_suspend() koja određuje ponašanje kada se korutina prvi put pokrene. Std::suspend_never znači da korutina ne bi trebala biti obustavljena u početku.

Nakon toga, imamo funkciju final_suspend() koja određuje ponašanje kada korutina treba završiti. Std::suspend_never znači da korutinu ne treba obustaviti prije finalizacije.

Ako korutina izbaci iznimku, poziva se metoda unhandled_exception(). U ovom primjeru, to je prazna funkcija, ali možete rukovati iznimkama po potrebi. Kada korutina završi bez davanja vrijednosti, poziva se metoda return_void(). U ovom slučaju, to je također prazna funkcija.

Također definiramo tri funkcije članice unutar “ThisCorout”. Funkcija await_ready() poziva se da provjeri je li korutina spremna za nastavak izvođenja. U ovom primjeru, uvijek vraća false što znači da korutina nije spremna odmah nastaviti. Kada će korutina biti obustavljena, poziva se metoda await_suspend(). Ovdje je to prazna funkcija što znači da obustava nije potrebna. Program poziva await_resume() kada se korutina nastavi nakon obustave. Samo ispisuje poruku koja navodi da je korutina nastavljena.

Sljedeći redovi koda definiraju funkciju korutine foo(). Unutar foo(), počinjemo ispisivanjem poruke koja navodi da je korutina pokrenuta. Zatim se co_await std::suspend_always{} koristi za obustavu korutine i označava da se može nastaviti kasnije. Naredba co_return koristi se za završetak korutine bez vraćanja bilo kakve vrijednosti.

U funkciji main() konstruiramo objekt 'cr' tipa 'ThisCorout' pozivom foo(). Ovo stvara i pokreće korutinu. Zatim se ispisuje poruka koja navodi da je korutina kreirana. Zatim pozivamo await_resume() na objektu korutine “cr” kako bismo nastavili s izvođenjem. Unutar await_resume(), ispisuje se poruka 'Korutina je nastavljena'. Na kraju, prikazujemo poruku koja navodi da je korutina dovršena prije nego što se program prekine.

Kada pokrenete ovaj program, rezultat je sljedeći:

Primjer 2: Korutina s parametrima i prinosom

Sada, za ovu ilustraciju, nudimo kod koji demonstrira upotrebu korutina s parametrima i prinosom u C++ za stvaranje ponašanja sličnog generatoru za proizvodnju niza brojeva.

#include

#include

#uključi

strukturirati NOVAKorutina {

strukturirati p_tip {

std :: vektor < int > vrijednosti ;

NOVAKorutina get_return_object ( ) { povratak { } ; }

std :: suspend_uvijek početna_obustava ( ) { povratak { } ; }

std :: suspend_uvijek konačna_obustava ( ) noexcept { povratak { } ; }

poništiti neobrađena_iznimka ( ) { }

poništiti return_void ( ) { }

std :: suspend_uvijek vrijednost_prinosa ( int vrijednost ) {

vrijednosti. odgurnuti ( vrijednost ) ;

povratak { } ;

}

} ;

std :: vektor < int > vrijednosti ;

strukturirati iterator {

std :: ručica_korutine <> chorus_ručka ;

bool operator != ( konst iterator i drugo ) konst { povratak chorus_ručka != drugo. chorus_ručka ; }

iterator i operater ++ ( ) { chorus_ručka. nastaviti ( ) ; povratak * ovaj ; }

int operater * ( ) konst { povratak chorus_ručka. obećanje ( ) . vrijednosti [ 0 ] ; }

} ;

iterator započeti ( ) { povratak iterator { std :: ručica_korutine < p_tip >:: od_obećanja ( obećanje ( ) ) } ; }

kraj iteratora ( ) { povratak iterator { nullptr } ; }

std :: ručica_korutine < p_tip > obećanje ( ) { povratak
std :: ručica_korutine < p_tip >:: od_obećanja ( * ovaj ) ; }

} ;

NOVOKorutina generira brojeve ( ) {

su_prinos 5 ;

su_prinos 6 ;

su_prinos 7 ;

}

int glavni ( ) {

NOVOKorutina nc = generirati Brojeve ( ) ;

za ( int vrijednost : nc ) {

std :: cout << vrijednost << ' ' ;

}

std :: cout << std :: endl ;

povratak 0 ;

}

U prethodnom kodu, struktura NEWCoroutine predstavlja generator temeljen na korutini. Sadrži ugniježđenu strukturu 'p_type' koja služi kao tip obećanja za korutinu. Struktura p_type definira funkcije koje su potrebne za stroj korutine kao što su get_return_object(), initial_suspend(), final_suspend(), unhandled_exception() i return_void(). Struktura p_type također uključuje funkciju yield_value(int value) koja se koristi za dobivanje vrijednosti iz korutine. Dodaje danu vrijednost vektoru vrijednosti.

Struktura NEWCoroutine uključuje varijablu člana std::vector koja se naziva 'vrijednosti' koja predstavlja generirane vrijednosti. Unutar NEWCoroutine nalazi se ugniježđeni iterator strukture koji omogućuje ponavljanje preko generiranih vrijednosti. Sadrži coro_handle koji je ručica korutine i definira operatore kao što su !=, ++ i * za iteraciju.

Koristimo funkciju begin() za stvaranje iteratora na početku korutine dobivanjem coro_handle iz obećanja p_type. Dok end() funkcija stvara iterator koji predstavlja kraj korutine i konstruiran je s nullptr coro_handle. Nakon toga, funkcija promise() se koristi za vraćanje vrste obećanja stvaranjem coroutine_handle iz obećanja p_type. GenerateNumbers() funkcija je korutina koja daje tri vrijednosti – 5, 6 i 7 – pomoću ključne riječi co_yield.

U funkciji main(), instanca NEWCoroutine pod nazivom “nc” kreirana je pozivanjem surutine generateNumbers(). Ovo inicijalizira korutinu i bilježi njeno stanje. Petlja 'for' koja se temelji na rasponu koristi se za ponavljanje preko vrijednosti 'nc', a svaka vrijednost se ispisuje koja je odvojena razmakom pomoću std::cout.

Generirani izlaz je sljedeći:

Zaključak

Ovaj članak pokazuje korištenje korutina u C++. Razgovarali smo o dva primjera. Za prvu ilustraciju, osnovna korutina kreirana je u C++ programu pomoću funkcija korutine. Dok je druga demonstracija provedena korištenjem korutina s parametrima i popuštanjem za generiranje ponašanja sličnog generatoru za stvaranje niza brojeva.