Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Kaip „Go Runtime“ tvarko kanalo operacijas iš vidaus


Kaip „Go Runtime“ tvarko kanalo operacijas iš vidaus


„Go Runtime“ tvarko kanalo operacijas iš vidaus per sudėtingą duomenų struktūrų koordinavimą, fiksavimo mechanizmus, gorutino planavimą ir sinchronizaciją, kad būtų užtikrintas efektyvus, sąžiningas ir be aklavietės ryšys tarp gorutinų.

„GO“ kanalai pirmiausia įgyvendinami kaip duomenų struktūra „HChan“, apimanti kanalo būseną, įskaitant jo buferį, laukiančių siuntėjų ir imtuvų eiles, sinchronizacijos primityvas ir meta informaciją, pavyzdžiui, ar kanalas uždarytas. Kai sukuriamas kanalas, krūvoje paskirstomas „hchan“ egzempliorius, o kanalo rodikliai nurodo vertę į šią struktūrą, leidžiančią keliems gorutinams juos remtis ir naudoti tuo pačiu metu.

Esant kanalui susideda iš:

- Apskritai buferinių kanalų buferis, vaizduojamas pjūvio ir indeksų „sendx“ ir „recvx“, kurie seka, kur galima siųsti ir gauti elementus. Buferio dydis yra fiksuotas kanalo kūrimu, ir jis veikia kaip eilutė, kurioje kaupiami siunčiami elementai, bet dar negauti.
- Dvi „FIFO Wait“ eilės (susieti sąrašai), skirtos valdyti „Gorouzes“, užblokuotą siunčiant („sendq“) ir gauti („RECVQ“). Šios „Queues“ saugo „Sudog“ struktūras, atspindinčias užblokuotą gorutiną ir susijusius duomenis apie kanalo operacijas, tokias kaip vertė siųsti, arba rodyklė, kur gauti vertę.
- „Mutex“ užraktas, skirtas apsaugoti lygiagrečią prieigą prie kanalo vidinių struktūrų, užtikrinant, kad siuntimo ir priėmimo operacijos palaikytų nuoseklumą ir nesugadintų kanalo būsenos, esančios kartu prieigoje.

kanalo siuntimo operacija

Kai gorutinas bando nusiųsti vertę kanalui („che operacija“

Gavimo operacija („Lexity“:

1. Užrakto įsigijimas: „Channel's Mutex“ yra užrakintas.

2. Patikrinkite, ar laukiantys siuntėjai: Jei yra siuntėjas, laukiantis „Sendq“:
- Imtuvas vertę paima tiesiogiai iš siuntėjo „Sudog“.
- Siuntėjas yra nenutrūkstamas ir pažymėtas.
- Abu gorutinai vyksta nedelsiant be buferumo.

3. Patikrinkite buferinius kanalus: jei nė vienas siuntėjas nelaukia:
- Kanalo patikrinimas, ar jo buferyje yra kokių nors elementų.
- Jei taip, elementas nukopijuojamas iš buferio padėties `buf [recvx]`.
- „RECVX“ rodyklė padidinta, o „QCount“ sumažinamas.
- Užraktas išleidžiamas, o imtuvas tęsiasi neužblokuodamas.

4. Imtuvo blokavimas: jei buferis tuščias ir nesitiki siuntėjas:
- imtuvo gorautinas pavaizduotas kaip „sudog“.
- Jis yra įtrauktas į „RECVQ“.
- Imtuvas yra pastatytas planuojančiu asmeniu, kol siuntimo operacija jį atblokuos.

5. Uždarytas kanalas gauna: jei kanalas uždarytas, o buferis tuščias:
- Gauna Grąžinkite elemento tipo nulinę vertę.
- Imtuvai neužblokuoja ir gali aptikti uždarą būseną pagal antrąjį loginį, grąžintą po priėmimo operacijos.

6. Sąžiningumas ir tvarka: laukiantys imtuvai yra ištiesti FIFO, kad išlaikytų sąžiningumą, o planavimas gerbia užsakymo apribojimus, tačiau negarantuoja griežtos tvarkos tvarkos dėl planavimo priemonės elgesio.

Parkavimo ir planavimo integracija

Kanalai yra glaudžiai integruoti su „Go“ „Goroutine“ planavimu, kuris valdo „Goroutine Lifecycles“, naudojant tris subjektus:

- G („Goroutine“): lengvas, vartotojo lygio sriegis.
- M (Mašina): OS gija, vykdanti „Goroutines“.
- P (procesorius): turi vietinę paleidžiamų gorutinų eilę ir išteklius, reikalingus „Go“ kodui vykdyti.

Kai kanalo operacija blokuoja (arba siųsti, arba gauti), goroutinas:

- pažymėtas kaip laukimas.
- pašalinta iš vietinės nuosavybės „p“ eilės.
- yra susieta per „sudog“ struktūrą atitinkamoje kanalo eilėje („Sendq“ arba „RECVQ“).
- Tuomet planuoklis pasirenka dar vieną bėgimą, kad galėtų paleisti tą „p“.

Kai užblokuota operacija bus paruošta baigti (pvz., Įvyks atitiktis siųsti ar gauti):

- Laukianti gorautinas yra išmestas iš kanalo eilės.
- pažymėtas bėgimas.
- Grįžta į vietinę ar pasaulinę planavimo eilę.
- Gorutinas galiausiai atnaujins vykdymą.

Šis dizainas vengia užimto ​​laukimo ir užtikrina efektyvų konteksto perjungimą su minimaliomis pridėtinėmis vertėmis, palyginti su tradiciniu OS gijų blokavimu.

kanalo uždarymo operacija

Uždaręs kanalą nustato „uždarą“ vėliavą „Hchan“, apsaugotą tuo pačiu muteksu. Kanalo uždarymas sukelia:

- Visi užblokuoti siuntėjai panikuoja, jei bandys išsiųsti.
- Visi užblokuoti imtuvai yra atblokuoti FIFO tvarka, kad gautų likusias buferines vertes, o po to nulinės vertės.
- Toliau gaunama nulinės vertės nedelsiant neužblokuodami.
- nedelsdami siunčiant uždarą kanalo paniką.
- Uždarymas taip pat sinchronizuojamas su kanalo operacijomis per „Mutex“, kad būtų išvengta lenktynių sąlygų.

Vidinės duomenų struktūros

- HCHAN: centrinis struct Holding:
- „Buf“ (buferio masyvo rodyklė)
- `dataqsiz` (buferio dydis)
- „QCount“ (šiuo metu buferinių elementų skaičius)
- „Sendx“, „RECVX“ (buferio indeksai)
- „Sendq“, „RECVQ“ (palaukite užblokuotų siuntėjų ir imtuvų eiles)
- „Uždaryta“ vėliava
- Įterptas mutex (siekiant apsaugoti būseną ir koordinuoti daugybę lygiagrečių operacijų).

- SUDOG: Vidinė vykdymo laiko struktūra, vaizduojanti kanalo operaciją laukiančioje žandikaulyje. Sulaiko:
- rodyklė į gorutiną.
- Rašytojai į siunčiamus ar gaunamus duomenis.
- Nuorodos į kitą „sudog“ laukimo eilėje.

- „WaitQ“: susietas „Sudogs“, atstovaujančių siunčiamiems padavėjams („Sendq“), sąrašas arba gaukite padavėjus („RECVQ“). Užtikrinant FIFO sąžiningumą.

Pasirinkite teiginį ir kanalus

„Go“ pareiškime „Select“ pateikia sudėtingumą, nes kelios kanalo operacijos konkuruoja vienu metu. Vykdymo laikas valdo kelias laukimo eiles kiekvienam pasirinktam atvejui, o pasirinkus iš kelių kanalų neprisijungę, apima:

- Bandant neužblokuoti operacijų kiekvienu atveju.
- Jei neišnyks, goroutino įvedimas į visas atitinkamas eiles.
- Kai gali vykti viena operacija, kiti padavėjai pašalinami, o „Goroutine“ atbloka.

Šis selektyvus laukimo mechanizmas yra labai integruotas su vykdymo planavimo priemone, kad būtų išlaikytas sąžiningumas ir efektyvumas.

Našumo ir suderinamumo aspektai

Kanalo dizainas siekia pusiausvyros tarp saugos ir našumo:

- „Mutex“ fiksavimas: užtikrina nuoseklumą, tačiau labai tvirtinant gali tapti kliūtimi. Vykdymo laikas trumpai palaiko užraktą, kad atomiškai atnaujintų būseną.
- Tiesioginis perdavimas: Jei įmanoma, venkite buferio pridėtinių išlaidų, leisdami greičiau bendrauti tarp gorutinų.
- Automobilių stovėjimo aikštelė ir neprilygstama: sumažina konteksto keitimo pridėtines vertes, palyginti su OS gijų.
- Sąžiningumas: vykdomas per FIFO eiles, kad būtų išvengta bado.
- Talpyklos ir vietovės: Nepakartojami gorutinai gali atnaujinti skirtinguose procesoriuose („p“), galbūt dėl ​​to, kad būtų galima praleisti talpyklą.
- Griaustinė bandos problema: kanalo ar transliavimo uždarymas gali pažadinti daugybę gorutinų vienu metu, kuriuos planuojamasis turi protingai tvarkyti.

Kanalai yra elegantiškas lygiagretumo primityvus, kuris sujungia užrakto apsaugotą žiedo buferį su gorutino planavimo mechanizmais, užtikrinant saugumą, užsakymą ir efektyvumą GO programose.

„Go Channel“ operacijų vidinės dalys atskleidžia griežtą duomenų struktūrų sujungimą, fiksavimo ir vykdymo planavimo priemonę, įterpiantį sinchronizaciją vartotojo lygio lengvuose sriegiuose ir įgalinant turtingus ryšio modelius be sunkių OS branduolių sąveikos. Šis požiūris išskiria „Go“ suderinamumo modelį ir yra pagrindinė priežastis, kodėl kanalai yra veiksmingi ir paprasti iš programuotojo perspektyvos.