Kas yra Coroutines C ++ 20?

Kas yra coroutines ?

Kaip jis skiriasi nuo „Paralelizmas2“ arba / ir „Konkretumas2“ (žr. Paveikslėlį žemiau)?

Toliau pateikiamas vaizdas iš ISOCPP.

https://isocpp.org/files/img/wg21-timeline-2017-03.png

2019

19 апр. Naidu nustatė balandžio 19 d 2017-04-19 21:39 '17 at 9:39 PM 2017-04-19 21:39
@ 3 atsakymai

Anot abstrakto lygio, Coroutines atskirė idėją turėti vykdymo būseną nuo idėjos turėti vykdymą.

SIMD (viena komanda, keletas duomenų) turi keletą „vykdymo sričių“, bet tik vieną vykdymo būseną (ji veikia tik su keliais duomenimis). Galbūt lygiagrečiai algoritmai yra šiek tiek panašūs, nes turite vieną „programą“, veikiančią skirtingais duomenimis.

Siūlai turi keletą „vykdymo sričių“ ir kelias vykdymo būsenas. Turite daugiau nei vieną programą ir daugiau nei vieną vykdymo sriegį.

„Coroutines“ turi keletą vykdymo būsenų, tačiau neturi nuosekliųjų siūlų. Turite programą, o programa turi būseną, tačiau ji neturi vykdymo temos.


Paprasčiausias coroutines pavyzdys yra generatoriai arba išvardyti elementai iš kitų kalbų.

Pseudokode:

 function Generator() { for (i = 0 to 100) produce i } 

Generator vadinamas, o pirmojo skambučio metu jis grąžina 0 . Jos būsena yra prisiminta (tiek, kiek būsena pasikeičia, priklausomai nuo coroutines įgyvendinimo), ir kitą kartą, kai jį vadinsite, jis tęsis ten, kur jis sustojo. Taigi grįžta 1 kitą kartą. Tada 2.

Galiausiai jis pasiekia ciklo pabaigą ir nukrenta nuo funkcijos pabaigos; baigėsi coroutine. (Tai, kas čia vyksta, priklauso nuo kalbos, apie kurią kalbame; pythone tai sukelia išimtį).

„Coroutines“ šią funkciją pristato „C ++“.

Yra dviejų rūšių coroutines; kamino ir be kamino.

„Coroutine“ be kamino saugo tik vietinius kintamuosius savo būsenoje ir vykdymo vietoje.

Stotelė coroutine saugo visą kaminą (pvz., Sriegį).

Kamščiai gali būti labai lengvi. Paskutinis perskaitytas sakinys iš esmės buvo apie savo funkcijos perrašymą į kažką panašaus į lambda; visi vietiniai kintamieji pereina į objekto būseną, o etiketės naudojamos eiti į / iš vietos, kur „coroutine“ pateikia „tarpinius“ rezultatus.

Vertės kūrimo procesas vadinamas „derliumi“, nes korutinai panašūs į kooperatyvą; Grįžtate vykdymo tašką atgal į skambintoją.

„Boost“ turi kamino korpusų įgyvendinimą; Tai leidžia jums skambinti funkcijai. Stackful coroutines yra galingesni, bet taip pat brangesni.


Yra daugiau Coroutines nei paprastas generatorius. Jūs galite tikėtis, kad coroutine yra korutinas, o tai leidžia jums konstruktyviai konstruoti coroutines.

Coroutines, pavyzdžiui, jei, kilpos ir funkcijų skambučiai, yra dar viena „struktūrizuoto perėjimo“ rūšis, kuri leidžia jums natūraliau išreikšti tam tikrus naudingus modelius (pvz., Baigtinius automatus).


Konkretus Coroutines diegimas C + + yra šiek tiek įdomus.

Pagrindiniu lygiu jis prideda kelis raktinius žodžius į C ++: co_return co_await co_yield , taip pat kai kurias bibliotekų rūšis, kurios dirba su jais.

Funkcija tampa coroutine, turinti vieną iš jų kūno. Taigi, nuo jų paskelbimo jie neatitinka funkcijų.

Kai vienas iš šių trijų raktinių žodžių naudojamas funkcijoje, atsiranda tam tikras standartinis privalomas grąžinimo tipo ir argumentų tyrimas, o funkcija paverčiama coroutine. Šiame tyrime kompiliatoriui nurodoma, kur išsaugoti funkcijos būseną, kai funkcija yra sustabdyta.

Paprasčiausias coroutine yra generatorius:

 generator<int> get_integers( int start=0, int step=1 ) { for (int current=start; current+= step) co_yield current; } 

co_yield sustabdo funkcijų vykdymą, išsaugo šią būseną generator<int> ir grąžina current vertę generator<int> .

Galite pakartoti per grąžintus sveikuosius skaičius.

co_await leidžia jums prijungti vieną „coroutine“ į kitą. Jei esate vienoje coroutine, ir jums reikia tikėtino dalyko (dažnai coroutines) rezultatų, prieš co_await progresuoti, jūs naudojate jį. Jei jie pasiruošę, tu tęsi tuoj pat; jei ne, sustabdykite darbą, kol laukiate laukiančio laukimo.

 std::future<std::expected<std::string>> load_data( std::string resource ) { auto handle = co_await open_resouce(resource); while( auto line = co_await read_line(handle)) { if (std::optional<std::string> r = parse_data_from_line( line )) co_return *r; } co_return std::unexpected( resource_lacks_data(resource) ); } 

load_data yra coroutine, kuri generuoja std::future kai nurodytas šaltinis yra atidarytas, ir mes sugebame išanalizuoti tašką, kuriame radome prašomus duomenis.

open_resource ir read_line yra tikriausiai asinchroniniai coroutines, kurie atidaro failą ir skaito linijas iš jo. co_await susieja sustabdymo būseną ir load_data su jų pažanga.

C ++ coroutines yra daug lankstesni nei tai, nes jie buvo įgyvendinti kaip minimalus kalbos funkcijų rinkinys per vartotojo erdvę. Naudotojų erdvės tipai veiksmingai nustato, kad co_return co_await ir co_yield - mačiau, kad žmonės jį naudoja co_await neprivalomoms išraiškoms įgyvendinti, kad co_await už tuščią pasirinktinį parametrą automatiškai co_await tuščią būseną į išorinį neprivalomą:

 modified_optional<int> add( modified_optional<int> a, modified_optional<int> b ) { return (co_await a) + (co_await b); } 

vietoj

 std::optional<int> add( std::optional<int> a, std::optional<int> b ) { if (!a) return std::nullopt; if (!b) return std::nullopt; return *a + *b; } 
69
29 мая '17 в 17:05 2017-05-29 17:05 atsakymą pateikė Yakk - Adam Nevraumont, gegužės 29 d., 17:17 , 17: 05-17: 05

Korutinas yra panašus į C funkciją, kuri turi kelias grąžinimo ataskaitas ir, antrą kartą pakviestą, neatlieka vykdymo funkcijos pradžioje, bet pirmojoje komandoje po ankstesnės grąžinimo. Ši vykdymo vieta yra išsaugota kartu su visais automatiniais kintamaisiais, kurie gyvena ant kopijos neturinčių procesorių funkcijų.

border=0

„Microsoft“ ankstesnis eksperimentinis „coroutine“ diegimas naudojo kopijuotus stelažus, kad galėtumėte net grįžti iš gilių įdėtų funkcijų. Tačiau šią versiją C ++ komitetas atmetė. Šį įgyvendinimą galite gauti, pavyzdžiui, naudojant „Boosts“ pluošto biblioteką.

7
04 нояб. atsakymas pateikiamas Lothar 04.11. 2017-11-04 04:39 '17 at 4:39 2017-11-04 04:39

Daroma prielaida, kad coroutines turėtų būti (C ++) funkcijomis, kurios gali „laukti“ kitai procedūrai ir pateikti viską, kas reikalinga pristabdytai, pristabdytai, laukiančiai, subroutinai. funkcija, kuri labiausiai domina „C ++“ žmones, yra ta, kad idealiu atveju coroutines neužima kamino erdvės ... C # jau gali kažką panašaus, kai laukia ir eina, bet C ++ gali tekti atstatyti, jį gauti.

lygiagrečiai daugiausia dėmesio skiriama problemų atskyrimui, kai problema yra susijusi su užduotimi, kurią programa turi užbaigti. šis problemų atskyrimas gali būti pasiektas keliais būdais ... paprastai tai yra tam tikra delegacija. Suderinamumo idėja yra ta, kad procesų serija gali būti vykdoma savarankiškai (problemų atskyrimas), o „klausytojas“ veda viską, kas atsiranda dėl šių individualių problemų, kur jis turėtų eiti. tai labai priklauso nuo tam tikros asinchroninės kontrolės. Yra keletas požiūrių į sutapimą, įskaitant į aspektą orientuotą programavimą ir kt. C # yra įgaliotas operatorius, kuris veikia gana gerai.

lygiagretumas skamba lygiagrečiai ir gali būti įtrauktas, bet iš tikrųjų tai yra fizinis dizainas, kuriame dalyvauja daugelis procesorių, kurie yra daugiau ar mažiau lygiagrečiai su programine įranga, kurie gali siųsti kodo dalis skirtingiems procesoriams, kur jis bus paleistas ir rezultatai bus gauti sinchroniškai.

1
19 апр. atsakymą pateikė dr t , balandžio 19 d 2017-04-19 21:55 '17 at 9:55 2017-04-19 21:55

Kiti klausimai dėl žymių arba Užduoti klausimą