Примери Ц++ корутина

Primeri C Korutina



Корутине пружају језичку функцију која вам омогућава да пишете асинхрони код на организованији и линеарнији начин, промовишући структурирани и секвенцијални приступ. Они дају механизам за паузирање и поновно покретање извршавања функције у одређеним инстанцама без заустављања целе нити. Корутине су корисне при руковању задацима који захтевају чекање на И/О операције као што је читање из датотеке или слање мрежног позива.

Корутине су засноване на концепту генератора где функција може дати вредности и касније бити настављена да би наставила са извршавањем. Корутине пружају моћан алат за управљање асинхроним операцијама и могу значајно побољшати укупан квалитет вашег кода.

Употреба корутина

Корутине су потребне из неколико разлога у савременом програмирању, посебно у језицима као што је Ц++. Ево неколико кључних разлога зашто су корутине корисне:







Корутине пружају елегантно решење за асинхроно програмирање. Они омогућавају креирање кода који изгледа секвенцијално и блокирајуће, о чему је лакше размишљати и разумети. Корутине могу да обуставе своје извршавање у одређеним тачкама без блокирања нити, омогућавајући паралелни рад других задатака. Због тога се системски ресурси могу ефикасније користити, а одзив је повећан у апликацијама које укључују И/О операције или чекање на екстерне догађаје.



Они могу учинити код лакшим за разумевање и одржавање. Елиминишући сложене ланце повратног позива или државне машине, корутине омогућавају да се код пише у линеарнијем и секвенцијалном стилу. Ово побољшава организацију кода, смањује угнежђење и чини логику лако разумљивом.



Корутине пружају структуиран начин за руковање конкурентношћу и паралелизмом. Они вам омогућавају да изразите сложене обрасце координације и асинхроне токове рада користећи интуитивнију синтаксу. За разлику од традиционалних модела нити у којима се нити могу блокирати, корутине могу ослободити системске ресурсе и омогућити ефикасан мултитаскинг.





Хајде да направимо неколико примера да демонстрирамо имплементацију корутина у Ц++.

Пример 1: Основне корутине

Основни пример корутина је дат у следећем:



#инцлуде <иостреам>

#инцлуде <корутина>

струцт ТхисЦороут {

струцт обећање_тип {

ТхисЦороут гет_ретурн_објецт ( ) { повратак { } ; }

стд :: суспенд_невер инитиал_суспенд ( ) { повратак { } ; }

стд :: суспенд_невер финал_суспенд ( ) ноекцепт { повратак { } ; }

празнина унхандлед_екцептион ( ) { }

празнина ретурн_воид ( ) { }

} ;

боол аваит_реади ( ) { повратак лажно ; }

празнина аваит_суспенд ( стд :: цороутине_хандле <> х ) { }

празнина аваит_ресуме ( ) { стд :: цоут << „Корутина је настављена.“ << стд :: ендл ; }

} ;

ТхисЦороут фоо ( ) {

стд :: цоут << „Корутина је почела.“ << стд :: ендл ;

цо_аваит стд :: суспенд_алваис { } ;

цо_ретурн ;

}

инт главни ( ) {

ауто кр = фоо ( ) ;

стд :: цоут << „Корутина је створена.“ << стд :: ендл ;

кр. аваит_ресуме ( ) ;

стд :: цоут << „Корутина је завршена.“ << стд :: ендл ;

повратак 0 ;

}

Хајде да прођемо кроз претходно наведени код и детаљно га објаснимо:

Након укључивања потребних датотека заглавља, дефинишемо структуру „ТхисЦороут“ која представља корутину. Унутар „ТхисЦороут“ дефинисана је друга структура која је „промисе_типе“ која рукује обећањем корутине. Ова структура обезбеђује различите функције које су потребне машини корутине.

Унутар заграда користимо функцију гет_ретурн_објецт(). Враћа сам објекат корутине. У овом случају, враћа празан објекат „ТхисЦороут“. Затим се позива функција инитиал_суспенд() која одређује понашање када се корутина први пут покрене. стд::суспенд_невер значи да корутина не би требало да буде суспендована у почетку.

Након тога, имамо функцију финал_суспенд() која одређује понашање када се корутина ускоро завршава. стд::суспенд_невер значи да корутину не треба суспендовати пре њеног финализације.

Ако корутина избаци изузетак, позива се метод унхандлед_екцептион(). У овом примеру, то је празна функција, али можете да обрађујете изузетке по потреби. Када се корутина заврши без давања вредности, позива се метода ретурн_воид(). У овом случају, то је такође празна функција.

Такође дефинишемо три функције члана у оквиру „ТхисЦороут“. Функција аваит_реади() се позива да провери да ли је корутина спремна да настави са извршавањем. У овом примеру увек враћа нетачно што указује да корутина није спремна да се одмах настави. Када ће корутина бити суспендована, позива се метод аваит_суспенд(). Овде је то празна функција што значи да суспензија није потребна. Програм позива аваит_ресуме() када се корутина настави након суспензије. Само шаље поруку која каже да је корутина настављена.

Следећи редови кода дефинишу функцију корутине фоо(). Унутар фоо(), почињемо штампањем поруке у којој се наводи да је корутина почела. Затим се цо_аваит стд::суспенд_алваис{} користи за суспендовање корутине и указује да се може наставити касније. Наредба цо_ретурн се користи за завршетак корутине без враћања било какве вредности.

У функцији маин() конструишемо објекат „цр“ типа „ТхисЦороут“ позивањем фоо(). Ово креира и покреће корутину. Затим се штампа порука која каже да је корутина креирана. Затим позивамо аваит_ресуме() на објекту корутине „цр“ да бисмо наставили његово извршавање. Унутар аваит_ресуме(), штампа се порука „Корутина је настављена“. На крају, приказујемо поруку која каже да је корутина завршена пре него што се програм заврши.

Када покренете овај програм, излаз је следећи:

Пример 2: Корутина са параметрима и приносом

Сада, за ову илустрацију, пружамо код који демонстрира употребу корутина са параметрима и попуштање у Ц++ за креирање понашања сличног генератору за производњу низа бројева.

#инцлуде <иостреам>

#инцлуде <корутина>

#инцлуде <вектор>

струцт НЕВЦороутине {

струцт п_типе {

стд :: вектор < инт > вредности ;

НОВАКорутина гет_ретурн_објецт ( ) { повратак { } ; }

стд :: суспенд_алваис инитиал_суспенд ( ) { повратак { } ; }

стд :: суспенд_алваис финал_суспенд ( ) ноекцепт { повратак { } ; }

празнина унхандлед_екцептион ( ) { }

празнина ретурн_воид ( ) { }

стд :: суспенд_алваис вредност_приноса ( инт вредност ) {

вредности. потисне ( вредност ) ;

повратак { } ;

}

} ;

стд :: вектор < инт > вредности ;

струцт итератор {

стд :: цороутине_хандле <> цхорус_хандле ;

боол оператор != ( конст итератор & друго ) конст { повратак цхорус_хандле != друго. цхорус_хандле ; }

итератор & оператер ++ ( ) { цхорус_хандле. Резиме ( ) ; повратак * ово ; }

инт оператер * ( ) конст { повратак цхорус_хандле. обећање ( ) . вредности [ 0 ] ; }

} ;

итератор почиње ( ) { повратак итератор { стд :: цороутине_хандле < п_типе >:: фром_промисе ( обећање ( ) ) } ; }

крај итератора ( ) { повратак итератор { нуллптр } ; }

стд :: цороутине_хандле < п_типе > обећање ( ) { повратак
стд :: цороутине_хандле < п_типе >:: фром_промисе ( * ово ) ; }

} ;

НЕВЦорутине генератеНумберс ( ) {

цо_ииелд 5 ;

цо_ииелд 6 ;

цо_ииелд 7 ;

}

инт главни ( ) {

НОВОЦороутине нц = генератеНумберс ( ) ;

за ( инт вредност : нц ) {

стд :: цоут << вредност << ' ' ;

}

стд :: цоут << стд :: ендл ;

повратак 0 ;

}

У претходном коду, структура НЕВЦороутине представља генератор заснован на корутини. Садржи угнежђену структуру „п_типе“ која служи као тип обећања за корутину. Структура п_типе дефинише функције које су потребне машини корутине као што су гет_ретурн_објецт(), инитиал_суспенд(), финал_суспенд(), унхандлед_екцептион() и ретурн_воид(). Структура п_типе такође укључује функцију ииелд_валуе(инт валуе) која се користи за добијање вредности из корутине. Он додаје дату вредност вектору вредности.

Структура НЕВЦороутине укључује променљиву члана стд::вецтор<инт> под називом „вредности“ која представља генерисане вредности. Унутар НЕВЦороутине, постоји угнежђени итератор структуре који омогућава итерацију преко генерисаних вредности. Садржи цоро_хандле који је ручица корутине и дефинише операторе као што су !=, ++ и * за итерацију.

Користимо функцију бегин() да креирамо итератор на почетку корутине тако што ћемо добити цоро_хандле из обећања п_типе. Док функција енд() креира итератор који представља крај корутине и конструисан је са нуллптр цоро_хандле-ом. Након тога, функција обећања() се користи за враћање типа обећања креирањем цороутине_хандле из обећања п_типе. ГенерирајНумберс() функција је корутина која даје три вредности – 5, 6 и 7 – користећи кључну реч цо_ииелд.

У функцији маин(), инстанца НЕВЦороутине под називом „нц“ се креира позивањем генериснумберс() корутине. Ово иницијализује корутину и бележи њено стање. Петља „фор“ заснована на опсегу користи се за понављање вредности „нц“, а свака вредност се штампа која је одвојена размаком помоћу стд::цоут.

Генерисани излаз је следећи:

Закључак

Овај чланак показује коришћење корутина у Ц++. Разговарали смо о два примера. За прву илустрацију, основна корутина је креирана у Ц++ програму користећи функције корутине. Док је друга демонстрација изведена коришћењем корутина са параметрима и генерисањем понашања сличног генератору за креирање низа бројева.