C++ korutīnu piemēri

C Korutinu Piemeri



Korutīnas nodrošina valodas līdzekli, kas ļauj rakstīt asinhrono kodu sakārtotākā un lineārākā veidā, veicinot strukturētu un secīgu pieeju. Tie nodrošina mehānismu, lai apturētu un restartētu funkcijas izpildi noteiktos gadījumos, neapturot visu pavedienu. Korutīnas ir noderīgas, veicot uzdevumus, kuros jāgaida I/O darbības, piemēram, nolasot no faila vai nosūtot tīkla zvanu.

Korutīnas ir balstītas uz ģeneratoru koncepciju, kur funkcija var dot vērtības un vēlāk to atsākt, lai turpinātu izpildi. Korutīnas nodrošina jaudīgu rīku asinhrono darbību pārvaldībai un var ievērojami uzlabot jūsu koda vispārējo kvalitāti.

Korutīnas lietojumi

Korutīnas ir nepieciešamas vairāku iemeslu dēļ mūsdienu programmēšanā, īpaši tādās valodās kā C++. Šeit ir daži galvenie iemesli, kāpēc korutīnas ir noderīgas:







Korutīnas nodrošina elegantu risinājumu asinhronai programmēšanai. Tie ļauj izveidot kodu, kas šķiet secīgs un bloķējošs, kuru ir vienkāršāk pamatot un saprast. Korutīnas var apturēt to izpildi noteiktos punktos, nebloķējot pavedienus, ļaujot paralēli darboties citiem uzdevumiem. Šī iemesla dēļ sistēmas resursi var tikt izmantoti efektīvāk, un tiek palielināta atsaucība lietojumprogrammās, kas ietver I/O operācijas vai gaida ārējus notikumus.



Tie var atvieglot koda izpratni un uzturēšanu. Likvidējot sarežģītās atzvanīšanas ķēdes vai stāvokļa mašīnas, korutīnas ļauj kodu rakstīt lineārākā un secīgākā stilā. Tas uzlabo koda organizāciju, samazina ligzdošanu un padara loģiku viegli uztveramu.



Korutīnas nodrošina strukturētu veidu, kā rīkoties ar vienlaicību un paralēlismu. Tie ļauj izteikt sarežģītus koordinācijas modeļus un asinhronās darbplūsmas, izmantojot intuitīvāku sintaksi. Atšķirībā no tradicionālajiem pavedienu veidošanas modeļiem, kur pavedieni var tikt bloķēti, korutīnas var atbrīvot sistēmas resursus un nodrošināt efektīvu vairākuzdevumu veikšanu.





Izveidosim dažus piemērus, lai demonstrētu korutīnu ieviešanu programmā C++.

1. piemērs. Pamatregulas

Pamatregulas piemērs ir sniegts tālāk.



#include

#include

struktūra ThisCorout {

struktūra solījumu_veids {

ThisCorout get_return_object ( ) { atgriezties { } ; }

std :: apturēt_nekad sākotnējā_apturēšana ( ) { atgriezties { } ; }

std :: apturēt_nekad final_suspend ( ) nē izņemot { atgriezties { } ; }

nederīgs neapstrādāts_izņēmums ( ) { }

nederīgs return_void ( ) { }

} ;

bool await_ready ( ) { atgriezties viltus ; }

nederīgs await_suspend ( std :: coroutine_handle <> h ) { }

nederīgs gaidiet_resume ( ) { std :: cout << 'Korutīna ir atsākta.' << std :: endl ; }

} ;

ThisCorout foo ( ) {

std :: cout << 'Korutīna ir sākusies.' << std :: endl ;

co_await std :: apturēt_vienmēr { } ;

co_return ;

}

starpt galvenais ( ) {

auto kr = foo ( ) ;

std :: cout << 'Korotīna ir izveidota.' << std :: endl ;

kr. gaidiet_resume ( ) ;

std :: cout << 'Korutīna pabeigta.' << std :: endl ;

atgriezties 0 ;

}

Izskatīsim iepriekš sniegto kodu un paskaidrosim to sīkāk:

Pēc nepieciešamo galvenes failu iekļaušanas mēs definējam “ThisCorout” struktūru, kas apzīmē korutīnu. Iekšpusē “ThisCorout” ir definēta cita struktūra, kas ir “promise_type”, kas apstrādā korutīnas solījumu. Šī struktūra nodrošina dažādas funkcijas, kas nepieciešamas korutīnas iekārtām.

Iekavās mēs izmantojam funkciju get_return_object(). Tas atgriež pašu korutīnas objektu. Šajā gadījumā tas atgriež tukšu “ThisCorout” objektu. Pēc tam tiek izsaukta funkcija inicial_suspend(), kas nosaka uzvedību, pirmo reizi startējot korutīnu. std::suspend_never nozīmē, ka korutīnu sākotnēji nevajadzētu apturēt.

Pēc tam mums ir funkcija final_suspend(), kas nosaka uzvedību, kad korutīna tuvojas beigām. std::suspend_never nozīmē, ka korutīnu nedrīkst apturēt pirms tās pabeigšanas.

Ja korutīna rada izņēmumu, tiek izsaukta unhandled_exception() metode. Šajā piemērā tā ir tukša funkcija, taču pēc vajadzības varat rīkoties ar izņēmumiem. Kad korutīna beidzas, nedodot vērtību, tiek izsaukta metode return_void(). Šajā gadījumā tā ir arī tukša funkcija.

Mēs arī definējam trīs dalībnieku funkcijas “ThisCorout” ietvaros. Funkcija await_ready() tiek izsaukta, lai pārbaudītu, vai korutīna ir gatava atsākt izpildi. Šajā piemērā tas vienmēr atgriež false, kas norāda, ka korutīna nav gatava nekavējoties atsākt. Kad korutīna tiks apturēta, tiek izsaukta metode await_suspend(). Šeit tā ir tukša funkcija, kas nozīmē, ka apturēšana nav nepieciešama. Programma izsauc await_resume(), kad korutīna tiek atsākta pēc apturēšanas. Tas tikai izvada ziņojumu, kurā teikts, ka korutīna ir atsākta.

Nākamās koda rindas nosaka foo () korutīnas funkciju. Iekšpusē foo () mēs sākam, izdrukājot ziņojumu, kurā teikts, ka korutīna ir sākusies. Pēc tam co_await std::suspend_always{} tiek izmantots, lai apturētu korutīnu, un tas norāda, ka to var atsākt vēlāk. Paziņojums co_return tiek izmantots, lai pabeigtu korutīnu, neatgriežot nekādu vērtību.

Funkcijā main() mēs izveidojam objektu “cr” ar tipu “ThisCorout”, izsaucot foo (). Tas izveido un sāk korutīnu. Pēc tam tiek izdrukāts ziņojums, kas norāda, ka korutīna ir izveidota. Pēc tam mēs izsaucam await_resume() korutīnas objektā “cr”, lai atsāktu tā izpildi. Laukā await_resume () tiek izdrukāts ziņojums “Koritīna ir atsākta”. Visbeidzot tiek parādīts ziņojums, kurā norādīts, ka pirms programmas darbības beigām pārbaudes ir pabeigtas.

Palaižot šo programmu, izvade ir šāda:

2. piemērs. Korutīna ar parametriem un ienesīgumu

Tagad šai ilustrācijai mēs piedāvājam kodu, kas parāda korutīnu izmantošanu ar parametriem un piekāpšanos valodā C++, lai izveidotu ģeneratoram līdzīgu uzvedību, lai izveidotu skaitļu virkni.

#include

#include

#iekļaut

struktūra JAUNA Korutīna {

struktūra p_type {

std :: vektors < starpt > vērtības ;

NEWCoroutine get_return_object ( ) { atgriezties { } ; }

std :: apturēt_vienmēr sākotnējā_apturēšana ( ) { atgriezties { } ; }

std :: apturēt_vienmēr final_suspend ( ) nē izņemot { atgriezties { } ; }

nederīgs neapstrādāts_izņēmums ( ) { }

nederīgs return_void ( ) { }

std :: apturēt_vienmēr ražas_vērtība ( starpt vērtību ) {

vērtības. atgrūst ( vērtību ) ;

atgriezties { } ;

}

} ;

std :: vektors < starpt > vērtības ;

struktūra iterators {

std :: coroutine_handle <> chorus_handle ;

bool operators != ( konst iterators & cits ) konst { atgriezties chorus_handle != cits. chorus_handle ; }

iterators & operators ++ ( ) { chorus_handle. turpināt ( ) ; atgriezties * šis ; }

starpt operators * ( ) konst { atgriezties chorus_handle. solījums ( ) . vērtības [ 0 ] ; }

} ;

iterators sākas ( ) { atgriezties iterators { std :: coroutine_handle < p_type >:: from_promise ( solījums ( ) ) } ; }

iteratora beigas ( ) { atgriezties iterators { nullptr } ; }

std :: coroutine_handle < p_type > solījums ( ) { atgriezties
std :: coroutine_handle < p_type >:: from_promise ( * šis ) ; }

} ;

NEWCoroutine generateNumbers ( ) {

co_ienesums 5 ;

co_ienesums 6 ;

co_ienesums 7 ;

}

starpt galvenais ( ) {

NEWCoroutine nc = GeneNumbers ( ) ;

priekš ( starpt vērtību : nc ) {

std :: cout << vērtību << ' ' ;

}

std :: cout << std :: endl ;

atgriezties 0 ;

}

Iepriekšējā kodā struktūra NEWCoroutine ir korutīnas ģenerators. Tas satur ligzdotu 'p_type' struktūru, kas kalpo kā korutīnas solījuma veids. Struktūra p_type definē funkcijas, kas ir nepieciešamas korutīnas mehānismam, piemēram, get_return_object(), origin_suspend(), final_suspend(), unhandled_exception() un return_void(). Struktūra p_type ietver arī funkciju return_value(int value), kas tiek izmantota, lai iegūtu vērtības no korutīnas. Tas pievieno sniegto vērtību vērtību vektoram.

Struktūra NEWCoroutine ietver std::vector dalībnieka mainīgo, ko sauc par 'vērtībām', kas attēlo ģenerētās vērtības. NEWCoroutine iekšpusē ir ligzdots struktūru iterators, kas ļauj atkārtot ģenerētās vērtības. Tajā ir coro_handle, kas ir korutīnas rokturis, un iterācijai definē operatorus, piemēram, !=, ++ un *.

Mēs izmantojam start() funkciju, lai izveidotu iteratoru korutīnas sākumā, iegūstot coro_handle no solījuma p_type. Tā kā funkcija end() izveido iteratoru, kas attēlo korutīnas beigas un ir konstruēts ar nullptr coro_handle. Pēc tam funkcija solījums () tiek izmantota, lai atgrieztu solījuma veidu, izveidojot coroutine_handle no solījuma p_type. Funkcija generateNumbers() ir korutīna, kas nodrošina trīs vērtības — 5, 6 un 7, izmantojot atslēgvārdu co_yield.

Funkcijā main() tiek izveidots NEWCoroutine gadījums ar nosaukumu “nc”, izsaucot korutīnu generateNumbers(). Tas inicializē korutīnu un uztver tās stāvokli. Uz diapazonu balstīta “for” cilpa tiek izmantota, lai atkārtotu “nc” vērtības, un katra vērtība tiek drukāta, kas ir atdalīta ar atstarpi, izmantojot std::cout.

Ģenerētā izvade ir šāda:

Secinājums

Šis raksts parāda korutīnu izmantošanu C++. Mēs apspriedām divus piemērus. Pirmajā ilustrācijā pamata korutīna tiek izveidota C++ programmā, izmantojot korutīnas funkcijas. Savukārt otrā demonstrācija tika veikta, izmantojot korutīnas ar parametriem un ļaujoties ģenerēt ģeneratoram līdzīgu uzvedību, lai izveidotu skaitļu secību.