- Coroutines waxay guud ahaan u habeeyaan hawlgallada hoose iyagoo ilaalinaya gobolka maxalliga ah isla markaana dib u bilaabaya fulinta goobaha joojinta, taasoo suurtogalinaysa muujinta dabiiciga ah ee mashiinnada gobolka, matoorada iyo isku-darka iskaashiga.
- Hirgelinta C waxay ka soo baxday maaraynta xidhmooyinka gacanta iyo POSIX macnaha APIs ilaa qiyaasaha ku salaysan macro iyo maktabadaha coroutine ee la qaadi karo oo lagu dhisay beddelka macnaha guud ee isticmaalaha.
- C++20 wuxuu jaangooyaa qaabka coroutine-ka aan la isku dhejin oo leh ballanqaadyo,
co_await,co_yieldiyo qaab-dhismeedyada coroutine, oo u oggolaanaya maktabadaha inay qeexaan soo koobitaanno heer sare ah oo aan isku mid ahayn iyo kuwa soo saara. - Qaabka caadiga ah, oo ay weheliso kuwa sugaya iyo noocyada ballanqaadka gaarka ah, wuxuu mideeyaa isticmaalka coroutine ee maktabadaha oo dhan isagoo ilaalinaya waxqabadka la saadaalin karo iyo xakamaynta.
Coroutines waxay ku fadhiyaan meel dhexe oo xiiso leh oo u dhaxaysa hawlaha caadiga ah iyo dunta oo si buuxda u buuxsantay, iyo sheekadooda laga bilaabo xeeladaha heerka hoose ee C ilaa taageerada luqadda C++20 ee caadiga ah waa mid ka mid ah isbeddellada ugu xiisaha badan ee barnaamijyada nidaamyada casriga ah. Haddii aad waligaa isku dayday inaad isku xirto wicitaanada dib-u-celinta, mashiinnada gobolka iyo isku-dubaridka dunta si aad u maareyso I/O aan xannibnayn, waxaad horey ula kulantay nooca xanuunka loo sameeyay coroutines si loo yareeyo.
Maqaalkan waxaan ku dul mari doonnaa sida coroutines uga soo baxeen hacks-ka gacanta lagu sameeyay ee C iyo POSIX macnaha guud ee APIs una soo baxeen qaabka coroutines-ka C++20 ee heerka sare ah, oo aan is dulsaarnayn, sharraxaadda waxa coroutine dhab ahaantii yahay, sida uu uga duwan yahay matoorada, dunta iyo fiilooyinka, waxa "istaag badan" iyo "istaag la'aanta" macnaheedu yahay, iyo sida mashiinnada C++20 (walxaha ballanqaadka, gacan-qabashada coroutine, co_await, co_yield, co_return) dhab ahaantii wuxuu ku dhaqmaa hooska.
Waa maxay coroutine, runtii?
Ma jiro qeexitaan rasmi ah oo caalami ahaan la aqbalay oo ku saabsan coroutine, laakiin suugaantu waxay isku urursan tahay laba astaamood oo muhiim ah oo kala sooca coroutines-ka iyo kuwa caadiga ah:
- Gobolka maxalliga ah ayaa ka badbaaday ganaaxyo kala duwan: xogta maxalliga ah ee coroutine waxay sii socotaa inta u dhaxaysa firfircoonida, sidaa darteed tusaale kasta oo coroutine ah wuxuu u dhaqmaa sida shay leh xasuus.
- Fulintu way joogsan kartaa oo dib ayay uga bilaabi kartaa isla qodobkaas: Marka kontaroolku ka tago coroutine, waxaa dib loogu celin karaa barta saxda ah ee joojinta halkii laga bilaabi lahaa dusha sare sida shaqo caadi ah.
Halkii ay ka heli lahaayeen hal gelitaan iyo bixitaan hal mar ah sida hawlgallada hoose, coroutines waxay taageeraan meelo badan oo laga galo iyo laga baxo inta ay nool yihiin, taas oo ka dhigaysa kuwo awood u leh muujinta soo saarayaasha, macaamiisha, mashiinnada gobolka, jadwalayaasha iskaashiga iyo socodka shaqada ee aan isku mid ahayn qaab toosan oo la akhrin karo.
Cabbirrada asaasiga ah ee naqshadeynta coroutine
Nidaamyada coroutine-ka ee adduunka dhabta ah waxay ku kala duwan yihiin saddex dhidib oo muhiim ah oo qeexaya sida ay u dhaqmaan iyo sida ay u muujiyaan: qaabka wareejinta xakamaynta, haddii coroutines ay yihiin qiimayaal heerka koowaad ah, iyo inay yihiin kuwo is dul saaran ama aan is dul saaranayn.
Marka hore, habka wareejinta xakamaynta ayaa kala soocaya coroutine-yada aan sinnayn iyo kuwa isku-dhafan. Naqshad aan sinnayn, coroutine-ka firfircoon wuxuu dib ugu soo celin karaa oo keliya qofka si toos ah u soo wacaya (iyadoo la adeegsanayo hawlgal fikrad ahaan la mid ah yield), qofka soo wacayna wuu dib u bilaabayaa ka dib (iyadoo la adeegsanayo hawlgal la mid ah resume) Naqshadaha isku dheelitiran, coroutine-ku si cad ayuu ugu wareejin karaa xakamaynta coroutine kasta oo kale, halkii uu had iyo jeer ku soo laaban lahaa ciddii ku baaqday.
Marka labaad, luqadaha qaar waxay ula dhaqmaan dhacdooyinka coroutine inay yihiin walxo heer sare ah oo aad kaydin karto, gudbin karto oo si xor ah u maareyn karto, halka kuwa kalena ay kaliya u soo bandhigaan coroutines inay yihiin dhismayaal isku dhafan oo leh siyaabo xaddidan oo loola macaamilo. Taageerada heerka koowaad si weyn ayay u kordhisaa dabacsanaanta iyo isku-dhafka.
Saddexaad, coroutines waxay noqon karaan kuwo is dul saaran ama aan is dul saaranayn. Coroutine-ka is dul saaran wuxuu si qoto dheer ugu xidhmi karaa gudaha xidhmo wicitaan oo buul leh; marka uu dib u bilaabo, qaab kasta oo ku jira xidhmadaas wuxuu ku sii socdaa meeshii uu ka joogsaday. Coroutine-ka is dul saaran wuxuu ku dheggan yahay oo keliya heerka shaqada coroutine-ka laftiisa: hawlaha caawiyaha joogtada ah ma soo bixi karaan ilaa ay iyagu yihiin coroutines ama si gaar ah loogu sharraxay.
Ereyga "coroutine buuxa" waxaa loo soo jeediyay isku-darka ugu muujinta badan: coroutine isku dhafan, oo heerka koowaad ah, oo isku mid ah ama aan sinnayn, taas oo awood ku filan u leh inay muujiso sii socoshada hal-toob ama sii socoshada xaddidan. Inkasta oo qaababka isku-dhafan iyo kuwa aan sinnayn ay leeyihiin awood muujin oo isku mid ah, qaabka aan sinnayn badanaa wuxuu u muuqdaa mid 'caadi ah' oo ay yaqaanaan inta badan barnaamij-sameeyayaasha.
Nidaamyada hoose, coroutines, matoorada iyo dunta
Hawlaha hoose waxaa loo arki karaa kiis gaar ah oo coroutines ah oo leh socodka xakamaynta oo aad u xaddidan iyo dhaqanka xaaladda. Shaqada caadiga ah had iyo jeer waxay ka bilaabataa tilmaamaheeda ugu horreeya, waxay ka baxdaa hal mar, waxayna tuurtaa xaaladdeeda maxalliga ah ka dib. Coroutine-ka, si ka duwan, wuxuu u wareejin karaa xakamaynta coroutines kale, dib ayaa loo bilaabi karaa goor dambe barta wax soo saarka, wuxuuna xaaladdiisa ku hayn karaa wareejintan. Tusaalooyin badan oo coroutine ah oo isku shaqo ah ayaa laga yaabaa inay wada noolaadaan, mid walbana wuxuu leeyahay xogtiisa maxalliga ah ee la ilaaliyo.
Jiil-dhaliyuhu wuxuu sameeyaa qayb la taaban karo oo ka mid ah coroutines, mararka qaarkoodna loo yaqaan "semicoroutines". Sida coroutines, matooradu waxay joojin karaan fulinta dhowr jeer ka dibna way sii wadi karaan, laakiin had iyo jeer waxay dib ugu noqdaan qofka si toos ah u soo waca mana haystaan hab ay fulinta ugu wareejiyaan coroutine saddexaad oo aan loo meel dayin. Xaddidaaddaas waa mid ula kac ah: matoorada waxaa loo habeeyay hirgelinta soo noqnoqoshada iyo taxanaha caajiska ah halkaas oo mid walba uu yield si fudud macnaheedu waa "soo saar qiime qof kasta oo i soo celinaya".
Xaqiiqdii, waxaad ku dayan kartaa coroutines-ka guud ahaan adigoo ku dhejinaya qalab dira oo dusha sare ka saaraya nidaamka matoorka korontada, tusaale ahaan iyadoo la haysto trampoline heer sare ah oo qaata calaamadaha matoorada isla markaana go'aamiya matoorka uu shaqeynayo marka xigta. Farsamadan waxaa taariikh ahaan loo isticmaali jiray luqadaha sida noocyada Python ee hore, kuwaas oo lahaa matoorro koronto oo keliya laakiin aan lahayn astaamo hore oo coroutine ah.
Coroutines badanaa waxaa lagu barbar dhigaa mowduucyada, laakiin waxay aasaas ahaan ku saabsan yihiin jadwalka iskaashiga halkii ay ka ahaan lahaayeen isbarbardhigga kahor. Coroutines waxay bixiyaan isku-dhafnaan macnaha ah in la iska dhaafo hawlaha iyada oo aan la beddelin macnaha guud, haddana isku mar kuma shaqeeyaan xudunta badan ee isku midka ah. Coroutine wuxuu kaliya xakameeyaa meelaha joojinta ee cad, sidaa darteed koodhka u dhexeeya qodobbadaas wuxuu ku shaqeeyaa iyada oo aan laga joojin coroutines-ka kale.
Qaabkan iskaashiga ah wuxuu meesha ka saarayaa madax-xanuunno badan oo isku-dhafan oo caadi u ah mawduucyada: Maadaama hal coroutine oo keliya uu ku shaqeeyo jadwaliye gaar ah, badanaa uma baahnid mutexes ama hawlgallada atomiga ee xaaladda caadiga ah ee la wadaago. Dhanka kale, coroutines-ku keligood ma isticmaali doonaan xudunta CPU-ga badan ilaa aad ku darto dunta ama fuliye badan oo dunta badan leh.
Tusaale ahaan coroutine-ka caadiga ah: soo-saare-macaamiil
Tusmada buug-yaraha ee coroutines-ka isku-dhafan waa qaabka soo-saaraha-macaamilka oo leh saf la wadaago. Hal coroutine ayaa soo saara alaab wuxuuna ku riixaa saf ilaa uu ka buuxsamo, ka dibna wuxuu u soo bandhigaa macaamiisha; macaamilku wuxuu soo dhigaa alaabta ilaa safka uu madhan yahay, ka dibna wuxuu u soo celiyaa soo saaraha. Hawlgalku wuu soo boodaa iyadoo dhinac kastaa uu si wadajir ah u bixiyo xakamaynta.
Hirgelinta noocaas ah, soo-saaraha iyo macaamiisha waxay u muuqdaan inay "is barbar socdaan" marka loo eego aragtida barnaamij-sameeyaha, inkastoo ay dhab ahaantii dib iyo dib ugu boodayaan hal dun oo fulin ah. Looma baahna dunta heerka OS-ga ama beddelka macnaha guud: hawlgalka wax soo saarku wuxuu noqon karaa boodbood heer hoose ah oo dib u habeeya qaab-dhismeedka firfircoon ee stack-ka.
Tusaalahan waxaa badanaa loo isticmaalaa in lagu soo bandhigo akhrinta badan, laakiin waa muhiim in la ogaado in coroutines-ka keliya ay ku filan yihiin in lagu muujiyo macquulka, iyo in lagu beddelo dunta ay noqon karto mid aan loo baahnayn ama xitaa waxyeello leh deegaannada danaynaya dammaanadda waqtiga-dhabta ah ama kharashka ugu yar ee waqtiga-socodka.
Sababta coroutines muhiim u tahay: mashiinnada gobolka, jilayaasha iyo socodka shaqada ee aan isku mid ahayn
Sababtoo ah coroutines waxay haystaan barta fulinta iyo doorsoomayaasha maxalliga ah ee ku baahsan wax soo saarka, Waxay bixiyaan hab aad u dabiici ah oo lagu hirgeliyo mashiinnada gobolka ee adag iyada oo aan lahayn weedho wareejin oo ballaaran, calamo ama tirinno barnaamij oo cad. Barta joojinta hadda jirta waxay si dhab ah u matashaa xaaladda hadda jirta.
Coroutines sidoo kale si fiican ayay ugu habboon yihiin moodooyinka isku-dhafka ah ee jilayaasha, sida kuwa loo isticmaalo matoorada ciyaarta badan. Jilaa kasta waxaa loo hirgelin karaa sidii coroutine oo si joogto ah u siiya xakamaynta jadwalka dhexe, kaas oo hal jile ka daba socda mid kale ku maamula hal mawduuc. Shaqadan iskaashatada ah ee badan waxay meesha ka saaraysaa baahida loo qabo in la xiro inta badan iyadoo weli bixinaysa dhaqan jawaab celin ah.
Matoorada lagu dhisay coroutines waxay ku habboon yihiin inay la shaqeeyaan durdurrada iyo qaab-dhismeedka xogta, gaar ahaan marka aad rabto soo saarista qiimayaasha caajiska ah ee baahida loo qabo. Halkii qiimaha lagu riixi lahaa macaamiisha, matoorku wuxuu u oggolaanayaa macaamiisha inay qiimaha mid mid u soo jiidaan iyagoo adeegsanaya wareeg fudud.
Coroutines sidoo kale waxay ku iftiimaan qaababka isgaarsiinta sida dhuumaha iyo gudbinta hababka isku xigxiga (CSP), halkaas oo marxalad kasta ay tahay coroutine oo wax soo saarta marka ay sugto wax soo saar ama wax soo saar. Jadwal-sameeyaha ayaa markaa dib u bilaabaya coroutines marka kanaallada isgaarsiintoodu diyaar yihiin, taasoo siinaysa beddel qurux badan oo loogu talagalay wicitaanka dhacdooyinka culus.
Ugu dambeyntii, maktabado badan oo tirooyin ah ayaa isticmaala qaab mararka qaarkood loo yaqaan "isgaarsiinta dib u noqoshada", halkaas oo xaliluhu uu istaajiyo mar kasta oo uu u baahdo isticmaaluhu inuu bixiyo qiimeyn shaqo, ka dibna uu dib u bilaabo marka isticmaaluhu ka jawaabo. Coroutines waxay bixiyaan hab toos ah oo la akhrin karo si loo muujiyo socodka xakamaynta ee gadaal iyo gadaal.
Laga bilaabo hirgelinta heerka hoose ee C ilaa maktabadaha la qaadi karo
Hal fasal oo ka mid ah hirgelinta ayaa si gacanta ah u hela xirmo wicitaan labaad ka dibna adeegsada setjmp/longjmp si aad u kala beddesho coroutines. Isku-dubaridka khadka tooska ah ee gaarka ah ee madal wuxuu dejin karaa xidhmo cusub oo loogu talagalay coroutine kasta; nidaamyada POSIX, calaamadaha oo lagu daray sigaltstack waxaa loo isticmaali karaa in lagu xiro fulinta xirmo kale oo ku jirta C saafi ah. Marka coroutine kasta uu leeyahay xidhmo u gaar ah, setjmp keydisaa xaaladda CPU iyo tilmaamaha kaydka, iyo longjmp waxay dib u soo celisaa si ay dib ugu bilaabaan coroutine-ka.
Qaar ka mid ah maktabadaha POSIX iyo UNIX-la jaanqaaday C ayaa taariikh ahaan soo bandhigay shaqooyin caawiya sida getcontext, setcontext, makecontext iyo swapcontext, taas oo si toos ah u koobaysa fikradda ah in loo beddelo xaaladaha heerka isticmaalaha. Inkasta oo kuwan tan iyo markaas lagu calaamadeeyay inay duugoobeen POSIX.1-2008, waxay sameeyeen laf-dhabarta maktabado badan oo coroutine ah waxayna dhiirigeliyeen naqshadihii dambe.
Hirgelinta ugu yar ee coroutine-ka setjmp/longjmp iyo API-yada macnaha guud, Beddelkeeda, waxaan dooranayaa isku-dubarid gacanta lagu qoray oo kaliya beddelaya miiska barnaamijka iyo tilmaamaha isku-darka, iyadoo la xirayo diiwaannada kale. Tani waxay si aad ah uga dhakhso badan kartaa ABI-yada qaarkood sababtoo ah waxay si sax ah u badbaadinaysaa waxa loo baahan yahay oo aan wax kale ahayn, halka setjmp waa inay si taxaddar leh u kaydisaa tiro badan oo diiwaanno ah.
Si looga qariyo dhibkan oo dhan koodhka codsiga, maktabado badan oo C ah ayaa soo muuqday sanadihii la soo dhaafay kuwaas oo xirmada coroutine u beddelaya APIs nadiif ah, sida Russ Cox's libtask iyo noocyo kala duwan oo kale (libpcl, coro, lthread, libcoro, libaco, libco iyo waxyaabo kaloo badan). Maktabadahani waxay caadi ahaan bixiyaan macluumaad kooban sida hawlo fudud ama fiilooyin la dib u bilaabi karo oo la soo saari karo iyada oo aan qofka soo wacaya u baahnayn inuu ka walwalo xeeladaha aasaasiga ah ee isu-imaatinka.
Coroutines qiyaas ahaan ku jira C iyadoo la adeegsanayo macros
Meelaha aan la heli karin ama la rabo in la isticmaalo API-yada kala duwan, horumariyayaashu waxay sidoo kale qiyaaseen coroutines-ka saafiga ah ee C oo leh macros iyo weedhaha badhanka, farsamo caan ku ah diiwaangelinta Simon Tatham oo la xiriirta khiyaanada "qalabka Duff" ee caadiga ah.
Fikradda ugu muhiimsan waa in la qeexo xaaladda coroutine-ka oo ah barnaamij lagu hirgeliyay a switch iyo case calaamado, meesha mid walba yieldMacro-sida oo kale ah wuxuu ku fidaa kood kaasoo diiwaangeliya calaamadda hadda jirta ee doorsoome aan isbeddelin ka dibna ku soo noqda qofka soo wacaya. Wicitaanka xiga, shaqadu waxay dib ugu booddaa calaamaddaas halkii ay ka bilaabi lahayd bilowga.
Maktabadaha sida Protothreads waxay ku dhisan yihiin qaabkan si ay u bixiyaan coroutines aad u fudud oo aan is dulsaarnayn oo ku habboon jawi xaddidan oo ku dhex jira, laakiin habkani wuxuu la socdaa xaddidaadyo halis ah: doorsoomayaasha maxalliga ah si dabiici ah uma sii jiraan wax soo saar ilaa ay ku kaydsan yihiin qaab-dhismeedyo aan joogto ahayn ama kuwa dibadda ah, si fudud uma joojin kartid wicitaanada shaqada ee ku dhex jira, guud ahaanna waxaad haysataa hal dhibic oo keliya oo laga galo.
Xitaa taageerayaashu waxay ku tilmaamaan khiyaanadan ku salaysan macro inay tahay mid ka mid ah koodka C ee ugu fool xun abid loo isticmaalo wax soo saarka, dhaleeceeyayaashuna waxay tilmaamayaan in socodka xakamaynta ee ka dhasha uu adkaan karo in laga fikiro oo la ilaaliyo waqti ka dib. Si kastaba ha ahaatee, waxay weli tahay tanaasul waxtar leh oo ku saabsan nidaamyada halkaas oo xirmooyin dheeraad ah ama khiyaamooyin isku xidhka ah aan la saadaalin karin.
Dhagaxa tallaabooyinka: fiilooyinka, dunta iyo waxyaabaha la xiriira
Deegaannada caadiga ah ee aan lahayn coroutines-ka asalka ah, dunta (iyo, ilaa xad yar, fiilooyinka) ayaa noqday xudunta dhismaha caadiga ah ee isku-dhafka, xitaa marka dhaqanka iskaashiga uu ku filnaan karo. Mawduucyada badanaa si fiican ayaa loo taageeraa oo si fiican ayaa loo diiwaangeliyaa, laakiin waxay xalliyaan dhibaato ballaaran oo ka adag tan kiisaska isticmaalka coroutine badankood ay dhab ahaantii u baahan yihiin.
Faybaraha, haddii la heli karo, waxay si dhow ula jaan qaadayaan coroutines-ka heerka isticmaalaha sababtoo ah si wada jir ah ayaa loo qorsheeyay waxaana la beddeli karaa iyada oo aan la isticmaalin OS-ka, iyaga oo ka dhigaya substrate dabiici ah oo lagu hirgelin karo API-yada qaabka coroutine. Si kastaba ha ahaatee, taageerada nidaamka ee fiilooyinka waa mid aan kala go 'lahayn marka loo eego dunta, oo la qaadi karo way dhib badan tahay.
Mid ka mid ah farqiga la taaban karo ee u dhexeeya mowduucyada iyo coroutines waa hab-dhaqanka jadwalka. Mawduucyada waxaa badanaa laga hor istaagaa meelaha aan kala sooca lahayn, taas oo ku qasabta barnaamij-sameeyayaasha inay ka fikiraan xaaladaha jinsiyadda iyo isku-dubaridka meel kasta. Coroutines, marka la barbardhigo, waxay kaliya beddelaan xakamaynta meelaha joojinta ee cad, taas oo inta badan kuu oggolaanaysa inaad qorto kood fudud iyada oo aan lahayn qufullo ama hawlgallo atomi ah.
Luqadaha iyo waqtiyada socodsiinta waxay sahamiyeen waddooyin badan oo lagu daydo coroutines marka lagu daro kaabayaasha jira, laga bilaabo dib u qorista bytecode (sida qaar ka mid ah qaab-dhismeedka coroutine Java) ilaa khariidaynta dhismayaasha coroutine-ka u eg ilaa kuwa soo noqnoqda (sida C# uu ku sameeyay yield ka hor async/await) ama ku dhisidda dusha sare ee dunta cagaaran, sii socoshada ama fiilooyinka.
Coroutines oo ku baahsan luuqadaha barnaamijyada
Tobanaan sano, luqado badan ayaa tijaabiyay qaab-dhismeedyo u eg coroutine, mid walbana leh dhadhan iyo is-weydaarsi u gaar ah. Fahmidda nidaamkan deegaanka waxay ka caawisaa in horumarka C++ la geliyo macnaha guud.
Luqadaha qaar waxay bixiyaan coroutines heer sare ah oo isku dhafan oo si toos ah ugu jira waqtiga shaqada iyo maktabadda caadiga ah. Tusaale ahaan, Lua waxay taageertay coroutines aan sinnayn oo is dul saaran tan iyo nooca 5.0 iyada oo loo marayo heerka caadiga ah. coroutine API, oo leh astaamo aasaasi ah si loo abuuro, loo bilaabo shaqada iyo wax soo saarka. Modula-2 taariikh ahaan waxaa ku jiray taageerada coroutine iyada oo loo marayo hababka sida NEWPROCESS iyo TRANSFER kuwaas oo dejiya istuudiyo gooni ah oo u kala beddela macnaha guud.
Nidaamyada kale ee deegaanka waxay dhiseen coroutines oo ka sarreeya waxyaabaha aasaasiga ah ee jira sida sii socoshada ama dunta cagaaran. Racket (iyo lahjadaha Scheme guud ahaan) waxay hirgelin karaan coroutines si aan caadi ahayn sababtoo ah waxay soo bandhigaan sii socoshada inay yihiin qiimayaal heerka koowaad ah. Nidaamyada Smalltalk, halkaas oo tirooyinka fulinta ay yihiin walxo la dhaqaajin karo, waxay sidoo kale martigelin karaan soo koobista coroutine iyada oo aan lahayn taageero VM dheeraad ah. OCaml, iswaafajinta iskaashiga ayaa la bixiyay iyada oo loo marayo modules kuwaas oo si horudhac ah u jadwaleeya mowduucyada hal dun oo OS ah, halka noocyada cusub ay ku daraan taageero qaabka cagaaran-mawduuca.
Luqadaha diiradda saaraya barnaamijyada aan isku mid ahayn badanaa waxay ku bilaabmaan matoorro ka hor inta aan la soo bandhigin coroutines buuxa. C# waxay markii hore ku dartay matoorro iyada oo loo marayo yield iyo qaabka soo noqnoqda, ka dibna wuxuu isu beddelay async/await si loogu qaabeeyo hawlgallada aan isku mid ahayn sida coroutines. JavaScript wuxuu raacay waddo la mid ah: ES2015 wuxuu soo bandhigay matoorro sida kiis gaar ah oo coroutines ah, noocyo dambena waa lagu daray async/await lagu dhisay ballanqaadyo iyo matoorro.
Dunida JVM, Java lafteedu ma bixiso coroutines-ka asalka ah, laakiin qalabka iyo luqadaha ku xeeran ayaa buuxiya farqiga. Maktabadaha qaar ayaa wax ka beddela bytecode si ay u matalaan dhaqanka coroutine, kuwa kalena waxay isticmaalaan JNI si ay u galaan farsamooyinka gaarka ah ee madal, qaarna waxay ku tiirsan yihiin dunta si ay ugu daydaan macnaha coroutine iyagoo kharash sare ku baxaya. Dhanka kale, Kotlin wuxuu bixiyaa coroutines oo ah astaamo maktabad oo dhinac koowaad ah wuxuuna la shaqeyn karaa koodhka Java (inkastoo Java si dabiici ah "hakin" u samayn karin oo waa inuu xannibaa ama adeegsadaa mustaqbalka).
Qorista iyo luuqadaha firfircoon waxay qaateen habab kala duwan. Python waxay ku bilaabatay matoorro la xoojiyay (PEP 342), waxayna ku kordhisay wakiilnimada matoorka hoosaadka (PEP 380), ugu dambayntiina waxay soo bandhigtay coroutines asal ah oo cad oo leh async/await (PEP 492), ka dibna keydinta ereyada muhiimka ah ee Python 3.7. Ruby wuxuu hirgeliyaa hab-dhaqanka u eg coroutine iyada oo loo marayo fiilooyinka; Raku iyo Tcl waxay bixiyaan qaab-dhismeedka coroutine ee asalka ah; PHP 8.1 wuxuu ku daray fiilooyin si uu u taageero maktabadaha ku salaysan coroutine ee I/O aan isku mid ahayn.
Luuqadaha ku salaysan nidaamka ayaa sidoo kale sahamiya moodooyinka u eg coroutine iyagoo wata qallooc u gaar ah. Go waxay isticmaashaa goroutines - habab fudud oo isku dhafan oo leh tirooyin cabbir ahaan firfircoon. Inkasta oo gorutines aysan ahayn coroutines macnaha adag (waxay u dhow yihiin dunta cagaaran, xogta maxalliga ahna kama badbaado 'wicitaanno' badan macnaha coroutine), waxay ku jiraan boos maskaxeed oo la mid ah hawlaha heerka isticmaalaha ee uu maamulo jadwal waqti-socod ah. D waxay soo bandhigaysaa coroutines iyada oo loo marayo Fiber maktabaddeeda caadiga ah, qaar ka mid ah qaab-dhismeedyaduna waxay ku duubaan is-dhexgal qaab-sameeye oo ku habboon.
Geli maktabadaha C++: ka hor heerka caadiga ah
Kahor coroutines-ka heerka C++, nidaamka deegaanka wuxuu ku tiirsanaa maktabado dhinac saddexaad ah si luqadda loogu soo bandhigo macnaha coroutine. iyadoo la adeegsanayo isku-darka beddelka macnaha guud ee isu-duwaha, API-yada goobta iyo metaprogramming template caqli badan.
Boost.Context wuxuu u muuqday aasaas heer hoose ah oo loogu talagalay in lagu beddelo macnaha guud ee fulinta qaab-dhismeedyo badan iyo nidaamyada hawlgalka, Iyadoo bixinaysa hab la qaadi karo oo lagu maareeyo meelaha isticmaalaha. Intaa waxaa dheer, Boost.Coroutine iyo Boost.Coroutine2 oo markii dambe soo bandhigay soo-saarista coroutine ee heerka sare ah, iyagoo ka gudbaya taageerada qaababka isku-dhafan iyo kuwa aan isku-dhafanayn una gudbaya is-dhexgal casri ah oo aan isku-dhafanayn oo si fiican ula jaanqaadaya weedhaha C++ ee casriga ah.
Mashruucyo kale ayaa sahamiyay xaglo kala duwan, sida coroutines-ka aan lahayn ee ku salaysan processor-ka ee ku dayanaya await/yield macnaha, maktabado hal-madaxle ah oo duuba fiilooyinka madal, ama qaab-dhismeedyo (sida Mordor ama Oat++ coroutines) kuwaas oo si gaar ah diiradda u saaraya qarinta dib-u-celinta I/O ee aan isku-xirnayn gadaasha koodka isku xigxiga ee u eg coroutine.
Nidaamyadan deegaanku waxay muujiyeen in horumariyayaasha C++ ay gaajaysan yihiin muujinta sida coroutine oo kale ah, laakiin waxay sidoo kale shaaca ka qaadeen dhibka xalalka aan caadiga ahayn: hab-raac aan isku mid ahayn, walaacyada la qaadi karo ee adag, khaladaadka iyo qalabka oo aan fiicnayn, iyo is-dhexgal aan fududayn oo lala yeesho inta kale ee maktabadda caadiga ah.
C++20 coroutines: qaab caadi ah oo aan is dulsaar lahayn
C++20 ugu dambeyntii waxay luqadda ku soo kordhisay coroutines iyadoo ah astaamo heer sare ah, laakiin leh naqshad si ula kac ah u yar oo heer hoose ah. Halkii loo rari lahaa soo koobid heer sare ah (sida "hawl", "matoor" ama "mustaqbal") maktabadda caadiga ah, C++20 waxay dejisay baloogyada dhismaha ee u oggolaanaya maktabadaha inay qeexaan noocyada u gaarka ah ee u habboon coroutine.
Shaqada waxay noqotaa coroutine haddii jirkeedu uu ka kooban yahay mid ka mid ah dhismayaasha gaarka u ah coroutine: ka co_await hawlwadeenku wuu joojin doonaa ilaa dhacdo ama qiimo diyaar ah la helo, co_yield muujinta si loo soo saaro qiimo oo loo hakiyo (sida matoorada), ama co_return bayaan si loo dhammaystiro coroutine-ka, ikhtiyaar ahaan natiijo ahaan.
Marka uu qalabku ogaado mid ka mid ah dhismayaashan, wuxuu shaqada u beddelaa mashiin xaaladdiisa joogtada ah lagu kaydiyo "qaab-dhismeed" oo loo qoondeeyay tuulmo, haddii aan hagaajintu caddayn in cimriga jirku uu si adag ugu dhex jiro qofka soo wacaya oo lagu dhex dari karo qaab-dhismeedka isku-xidhka qofka soo wacaya. Qaab-dhismeedkani wuxuu hayaa shayga ballanqaadka, nuqullada doodaha, doorsoomayaasha maxalliga ah ee ku nool meelaha joojinta iyo xogta xisaabinta si loo bilaabo fulinta.
Muhiimad ahaan, coroutine-ka C++20 waa kuwo aan is dulsaarnayn: Coroutine-ku wuxuu ku istaagi karaa oo keliya meelaha joojinta cad (co_await or co_yield) oo si cad uma soo saari karo wicitaanada aan kala sooca lahayn ilaa shaqooyinkaasi ay sidoo kale yihiin coroutines ama si kale uga qayb qaataan mishiinada coroutine. Tani waxay ka dhigaysaa hirgelinta mid fudud oo la saadaalin karo, iyadoo ku kacaysa awood muujin ah marka la barbar dhigo naqshadaha si buuxda u dhisan.
Xaddidaadaha iyo wareegga nolosha ee coroutine-ka C++20
Shaqo kasta oo ku jirta C++20 looma oggola inay noqoto coroutine; heerku wuxuu soo rogaa dhowr xayiraad si loo ilaaliyo caafimaadka moodeelka. Coroutines ma noqon karaan constexpr or consteval hawlaha, ma noqon karaan dhiseyaal, burburiyeyaal, ama main shaqada, mana isticmaali karaan doodaha kala duwan ee nooca C-style ama noocyada soo celinta booska sida caadiga ah auto iyada oo aan lahayn qeexitaan dheeraad ah.
Marka coroutine-ka marka hore la yiraahdo, isla markiiba uma dhaqmo sidii jir shaqo caadi ah. Taa beddelkeeda, hordhaca uu soo saaray compiler-ku wuxuu qoondeeyaa qaab-dhismeedka coroutine (badanaa iyada oo loo marayo operator new), wuxuu koobiyeeyaa xuduudaha shaqada qaab-dhismeedkaas (qiimo ahaan ama tixraac ahaan sida lagu dhawaaqay), wuxuu dhisaa shayga ballanqaadka ka dibna wuxuu wacaa promise.get_return_object(), kaas oo caadiyan soo saara gacan ama shay duuban oo loo celiyo qofka soo wacaya.
Shayga ballanqaadku waa nooc uu isticmaaluhu qeexay, oo laga helay iyada oo loo marayo std::coroutine_traits iyadoo lagu saleynayo nooca soo celinta coroutine iyo liiska xuduudaha, waxayna qeexaysaa sida natiijooyinka, ka-reebista iyo siyaasadaha joojinta u shaqeeyaan. Qoruhu wuxuu soo jeedinayaa a Promise qor ka dibna wac hababka sida initial_suspend(), final_suspend(), return_value() or return_void(), Iyo unhandled_exception() marxaladaha ku habboon ee wareegga nolosha ee coroutine.
Bilowgii fulinta, coroutine-ku wuxuu ku baaqayaa promise.initial_suspend() iyo co_awaitwax kasta oo soo noqda, taasoo u oggolaanaysa qorayaasha maktabadda inay go'aansadaan in nooca coroutine-koodu uu yahay "xiiso" (si dhakhso ah ayuu u bilaabmaa) ama "caajis" (wuxuu ku soo noqdaa qofka soo wacay ilaa si cad loo bilaabo). Marka coroutine-ku ugu dambeyntii dhammaado iyada oo loo marayo co_return ama ka reebitaan aan la maarayn, waxay soo jeedinaysaa promise.final_suspend(), iyadoo la siinayo maktabadda fursaddii ugu dambeysay ee ay ku jadwaleyn karto sii socoshada ama nadiifinta.
Marka qaab-dhismeedka coroutine-ka la burburiyo - ha ahaato dhammaystirka ka dib ama iyada oo loo marayo hawlgal burburin cad oo gacantiisa ah - Waqtiga runtime wuxuu burburiyaa shayga ballanqaadka, nuqullada xuduudaha iyo wixii kale ee deegaanka ah ee nool, ka dibna wuxuu xoreeyaa xusuusta operator delete (ama haddii la bixiyo qoondeeye gaar ah oo ballan-qaad ah). Haddii qoondayntu ay fashilanto oo ballanqaadku qeexayo get_return_object_on_allocation_failure(), coroutine-ku si qurux badan ayuu u tilmaami karaa guuldarada isagoon tuurin std::bad_alloc.
co_await, kuwa la filayo iyo kuwa sugaya
The co_await Hawl-wadeenku waa heerka ugu hooseeya ee joojinta nidaamka coroutine ee C++20, Fahmidda farsamoyaqaannadeedu waa muhiim u ah naqshadeynta naqshadaha aan isku mid ahayn ee adag.
Markaad qorto co_await expr; gudaha coroutine, compiler-ku wuxuu marka hore beddelaa expr galay shay "la sugi karo", ama adigoo sii maraya promise.await_transform(expr) haddii xubin noocaas ahi jirto, ama iyadoo u adeegsanaysa sida ay tahay. Kadibna waxay go'aaminaysaa shayga "suge" iyadoo wacaysa xubin operator co_await qofka la filayo, oo aan xubin ka ahayn operator co_await, ama si fudud ula macaamilka qofka la sugi karo sidii qofka sugaya haddii uusan jirin shaqaale noocaas ah.
Qofka sugaya waa inuu sameeyaa saddex hawlgal oo muhiim ah: await_ready(), await_suspend(handle) iyo await_resume(). If await_ready() run ayuu soo celiyaa, coroutine-ku ma hakiyo oo si toos ah ayuu u wacaa await_resume(), oo suurtogalinaysa waddooyin degdeg ah oo loogu talagalay hawlgallada hore loo dhammeeyay. Haddii ay soo celiso been, coroutine-ku wuu joogsanayaa, xaaladdiisa waxaa lagu kaydiyaa qaab-dhismeedka, iyo await_suspend() waxaa loogu yeeraa gacan ku haynta coroutine-ka hadda jira.
Gudaha await_suspend(), qofka sugaya ayaa go'aan ka gaari kara waxa uu ku samaynayo gacanta coroutine-ka: u qorshee dib u bilaabista dambe ee fulinta qaar, dib u bilow coroutine kale, ama xitaa dib u bilow isla coroutine-kii isla markiiba (iyadoo ku xiran nooca soo celinta iyo qiimaha await_suspend()Marka hawlgalka la sugayo uu dhammaado, qof ayaa ugu dambeyntii soo waca handle.resume(), markaas oo kontaroolku uu dib ugu soo laabto wax yar ka hor await_resume(), ka dibna await_resume() waxay keentaa natiijada isku-dhafka co_await muujinta.
Maktabadda caadiga ah waxay bixisaa laba waxyaalood oo aan caadi ahayn: std::suspend_always iyo std::suspend_never, kuwaas oo inta badan loo isticmaalo gudaha initial_suspend() iyo final_suspend() Hirgelinta si loo muujiyo bilow caajis ah ama xiiso leh iyo sida loo dhaqmo dhammaadka. Sugayaasha aadka u horumarsan waxay qaban karaan xaalad hawlgal kasta ah, tusaale ahaan inay coroutines ku xidhaan API-yada I/O ee aan isku mid ahayn, xaaladdaasina waxay ku nooshahay gudaha qaab-dhismeedka coroutine ee ka gudbaya barta joojinta.
co_yield iyo coroutines-ka qaabka dhaliyaha
The co_yield muujinta ayaa ka dhisan dusha sare co_await si loo taageero dhaqanka u eg dhaliyaha, halkaas oo coroutine uu si isdaba joog ah u soo saaro qiimayaal loogu talagalay qofka soo wacaya oo korkooda ku celceliya.
Fikrad ahaan, co_yield value; waxay ku fidaysaa wicitaan loo dirayo promise.yield_value(value) ka dibna ganaax, sida caadiga ah iyada oo loo marayo co_await std::suspend_always ama mid la mid ah oo la sugi karo. Hirgelinta ballanqaadku waxay mas'uul ka tahay kaydinta qiimaha la helay meel la heli karo (iyadoo la koobiyeynayo, la rari karo ama la tixgalinayo) si macaamilku u soo ceshan karo ka hor inta uusan dib u bilaabin coroutine-ka.
Koodhka maktabadda ee hirgeliya matoorada ayaa badanaa qeexa nooca ballanqaadka kaas oo soo bandhigaya hababka lagu heli karo qiimaha hadda la bixiyo iyo isku-darka hab-raacyada soo noqnoqoshada caadiga ah, sida bixinta adeegyada begin()/end() duubka gacanta iyo kor u qaadista coroutine-ka hoose ee kor u kaca kasta.
Maareynta khaladaadka, tixraacyada laalaada iyo faahfaahinta qarsoon
C++20 coroutines waxay la falgalaan maaraynta ka-reebista C++ iyada oo loo marayo ballanqaadka unhandled_exception() habka, kaas oo uu soo ururiyeyaashu ugu yeero haddii ka-reebitaan uu ka baxo jirka coroutine-ka. Coroutine-ku wuxuu markaa u gudbaa joojinta kama dambaysta ah, ballanqaadkuna waxaa la filayaa inuu diyaariyo in qaladka loo gudbiyo ciddii leh nooca natiijada coroutine-ka.
Sababtoo ah xuduudaha waxaa lagu koobiyeyyaa ama lagu tixgaliyaa qaab-dhismeedka coroutine-ka waqtiga abuurista, Waa in taxaddar la sameeyaa marka la eego xuduudaha tixraaca: haddii ay tilmaamayaan walxaha cimrigoodu dhammaado ka hor inta aan dib loo bilaabin coroutine-ka, coroutine-ku wuxuu ka fogaan karaa tixraacyada laalaada. Tani ma aha dhibaato gaar u ah coroutine, laakiin dabeecadda joogtada ah ee qaab-dhismeedka ayaa sahlaysa in si kama' ah looga noolaado walxaha la tixraacay.
Heerku wuxuu sidoo kale horumariyay si loo caddeeyo kiisaska geesaha iyada oo loo marayo warbixinnada cilladaha, sida in la sameeyo waxyaabo aan sax ahayn return_void qaab-dhismeedyo aan si fiican loo samayn halkii ay ka soo saari lahaayeen hab-dhaqan aan la qeexin marka ay ka dhacayaan dhammaadka coroutine, oo u oggolaanaya co_await xaalado badan sida lambda bodies.
Wadajir ahaan, xeerarkan iyo hagaajintani waxay qaabeeyaan qaab heer hoose ah laakiin la saadaalin karo kaas oo maktabadaha coroutine-ka ee heerka sare ah ay si ammaan ah u dhisi karaan, oo u dhexeeya matoorro fudud ilaa nidaamyada shaqada ee async/sugitaan buuxa oo lagu dhex daray fuliyayaal iyo jadwal-sameeyayaal.
Marka laga eego kor, safarka laga bilaabo xeeladaha isu-imaatinka ad-hoc ee C ilaa coroutines qaabaysan, aan is dulsaarnayn, oo ballanqaad leh oo C++20 ah waxay muujinaysaa riixitaan joogto ah oo ku wajahan soo-saarid ammaan ah oo la isku halayn karo si loo muujiyo socodka xakamaynta ee adag, hawlgallada aan isku mid ahayn iyo xisaabinta gobolka, iyada oo aan la joojin waxqabadka iyo xakamaynta ay barnaamij-sameeyayaasha nidaamku ku tiirsan yihiin.