Home Arrow Icon Knowledge base Arrow Icon Global Arrow Icon Kako se interno ukvarja z izvajanjem kanalov.


Kako se interno ukvarja z izvajanjem kanalov.


GO Runtime upravlja z operacijami kanalov interno s prefinjenim usklajevanjem podatkovnih struktur, zaklepajočih mehanizmov, načrtovanjem goroutina in sinhronizacijo, da bi zagotovili učinkovito, pošteno in brez mrtvega komunikacije med goroutini.

Kanali v GO se izvajajo predvsem kot podatkovna struktura "Hchan", ki zajema stanje kanala, vključno z njegovim medpomnilnikom, čakalnimi čakalnimi čakalnimi časi in sprejemniki, sinhronizacijskimi primitivi in ​​meta informacijami, na primer, ali je kanal zaprt. Ko je ustvarjen kanal, se na kopici dodeli primerek "hchan" in vrednost, ki predstavlja kanal, kaže na to strukturo, kar omogoča več goroutinov, da se lahko sklicuje in uporablja hkrati.

V središču je kanal sestavljen iz:

- Krožni medpomnilnik za puferirane kanale, ki ga predstavljajo rezina in indeksi `sendx` in` recvx`, ki sledijo, kam naj pošiljajo in sprejemajo elemente. Velikost medpomnilnika je določena na ustvarjanju kanalov in deluje kot čakalna vrsta, ki hrani elemente, poslane, vendar še niso prejete.
- Dve čakalni čakalni vrsti FIFO (povezani seznami) za upravljanje goroutinov, blokiranih pri pošiljanju (`sendq`) in prejemanju (` recvq`). Te čakalne vrste hranijo strukture "Sudog", ki predstavljajo blokirane goroutine in z njimi povezane podatke za operacije kanalov, kot je vrednost, ki jo je treba poslati, ali kazalec, kje sprejeti vrednost.
- Mutex ključavnica za zaščito sočasnega dostopa do notranjih struktur kanala in zagotavlja, da pošiljanje in sprejemanje operacij ohranja doslednost in ne poškoduje stanja kanala pod sočasnim dostopom.

kanal Pošlji operacijo

Ko goroutin poskuša poslati vrednost kanalu (`ch e operacija

Prejemanje (`lexity:

1. pridobivanje ključavnice: Mutex kanal je zaklenjen.

2. Preverite čakalnike: Če v `sendq` čaka pošiljatelj:
- Sprejemnik vzame vrednost neposredno iz "Sudog" pošiljatelja.
- Pošiljatelj je odstranjen in označen.
- Oba goroutina nadaljujeta takoj brez varovanja.

3
- Kanal preveri, ali njegov medpomnilnik vsebuje vse elemente.
- Če je tako, se element kopira iz položaja medpomnilnika `buf [recvx]`.
- Indeks `recvx` je povečan in` qcount` se zmanjšuje.
- Zaklep se sprosti in sprejemnik se nadaljuje brez blokiranja.

4. Blokiranje sprejemnika: Če je medpomnilnik prazen in noben pošiljatelj ne čaka:
- Goroutin sprejemnik je predstavljen kot "sudog".
- Enqueed v `recvq`.
- Sprejemnik parkira načrtovalec, dokler ga pošlje operacija ne odblodi.

5. Zaprti kanal prejme: Če je kanal zaprt in je medpomnilnik prazen:
- prejme vrnitev ničelne vrednosti vrste elementa.
- Sprejemniki ne blokirajo in lahko zaznajo zaprto stanje z drugim booleanom, vrnjenim iz operacije sprejema.

6. Pravičnost in naročilo: Čakalni sprejemniki se odpravijo na FIFO, da ohranijo poštenost, in načrtovanje spoštuje omejitve, vendar ne zagotavlja strogega časovnega reda zaradi vedenja načrtovalca.

Integracija parkiranja in načrtovanja

Kanali so tesno integrirani z Go -jevim goroutine Scheduler, ki upravlja z življenjskimi kolesi goroutine z uporabo treh entitet:

- G (goroutine): lahka, nit na ravni uporabnika.
- M (stroj): OS nit, ki izvaja goroutine.
- P (procesor): ima lokalno čakalno vrsto goroutinov in virov, potrebnih za izvajanje kode GO.

Ko delovanje kanala blokira (bodisi pošlje ali prejema), goroutine:

- je označena kot čakanja.
- je odstranjen iz lokalne čakalne vrste v lasti `p`.
- je povezan s strukturo `sudog` v ustrezni čakalni vrsti kanala (` sendq` ali `recvq`).
- Scheduler nato izbere še en goroutin, ki bo potekal na tem `P`.

Ko blokirano operacijo postane pripravljena na dokončanje (npr. Pošlji ali sprejema kolega):

- Čakalni goroutin je oddelan iz čakalne vrste kanalov.
- Označeno.
- Postavljeno nazaj na lokalno ali globalno čakalno vrsto za načrtovanje.
- Goroutine se bo sčasoma nadaljeval z izvedbo.

Ta zasnova se izogne ​​zasedenemu čakanju in zagotavlja učinkovito preklapljanje konteksta z minimalnimi režijskimi stroški v primerjavi s tradicionalnim blokiranjem niti OS.

Channel Close Operacija

Zapiranje kanala nastavi "zaprto" zastavo v `hchan`, zaščiteni z istim mutexom. Zapiranje kanala povzroči naslednje:

- Vsi blokirani pošiljatelji panično, če poskušajo poslati.
- Vsi blokirani sprejemniki so odblokirani v EFO vrstnem redu, da sprejmejo preostale puferirane vrednosti in nato ničelne vrednosti.
- nadalje prejme vrednosti povratne nič, ne da bi blokirali.
- takoj pošiljanje na zaprti kanal.
- Tesno delovanje je tudi sinhronizirano z operacijami kanalov skozi mutex, da se izognete dirki.

Notranje strukture podatkov

- Hchan: centralno strukturo:
- `buf` (kazalec medpomnilnika)
- `dataqsiz` (velikost medpomnilnika)
- `qcount` (štetje elementov, ki so trenutno varovani)
- `sendx`,` recvx` (indeksi medpomnilnikov)
- `sendQ`,` recvq` (čakajo na blokirane pošiljatelje in sprejemnike)
- `zaprta zastava
- vgrajen mutex (za zaščito stanja in usklajevanje več sočasnih operacij).

- Sudog: Notranja struktura izvajanja, ki predstavlja goroutine, ki čaka na kanalu. Drži:
- Kazalec na goroutine.
- Kazalci na podatke, ki se pošiljajo ali prejmejo.
- Povezave do naslednjega "Sudoga" v čakalni vrsti.

- waitQ: Povezani seznam sudogov, ki predstavljajo ali pošiljajo natakarje (`sendq`) bodisi sprejemajo natakarje (` recvq`). Zagotavljanje poštenosti FIFO.

Izberite stavek in kanali

GO -jev stavek `Select` uvaja zapletenost, ker več kanalov operacije tekmujejo hkrati. Runtime upravlja z več čakalnimi čakalnimi vrstami za vsak primer izbranega primera, izbira med več kanali pa vključuje:

- Poskus operacij, ki niso blokirali, v vsakem primeru.
- Če se ne nadaljuje, sprožite goroutine na vseh ustreznih čakalnih vrstah.
- Ko se lahko nadaljuje ena operacija, se drugi natakarji odstranijo in goroutine odbloki.

Ta selektivni mehanizem čakanja je globoko integriran s načrtovalcem izvajanja, da ohrani pravičnost in učinkovitost.

Uspešnost in sočasni premisleki

Oblikovanje kanala si prizadeva za ravnovesje med varnostjo in zmogljivostjo:

- Mutex zaklepanje: zagotavlja doslednost, vendar lahko postane ozko grlo v zelo visoki prepiri. Čas izvajanja ohranja ključavnico na kratko, da atomsko posodobi stanje.
- Neposredna predava: Izogibajte se režijskemu pobočju, kadar je to mogoče, kar omogoča hitrejšo komunikacijo med goroutini.
- Parkiranje in neobremenjenost: Minimizira kontekstno preklop nad glavo v primerjavi z navoji OS.
- Pravičnost: uveljavljena prek čakalnih vrst FIFO, da se prepreči stradanje.
- predpomnilnik in kraj: Neprijetni gorouti se lahko nadaljujejo z različnimi procesorji (`P`), kar lahko vodi v predpomnilnika.
- Thundering čreda: Zapiranje kanala ali oddajanje lahko hkrati zbudi številne goroutine, ki jih mora načrtovati preudarno.

Kanali predstavljajo eleganten sočasni primitiv, ki združuje pufer, zaščiten z zaklepanjem, z mehanizmi za načrtovanje goroutina, zagotavljanje varnosti, naročanja in učinkovitosti v programih GO.

Notranjo operacije kanalov GO razkrivajo tesno povezavo med podatkovnimi strukturami, zaklepanjem in načrtovalcem izvajanja, vgradijo sinhronizacijo v lahke niti na uporabniški ravni in omogočajo bogate komunikacijske vzorce brez težke interakcije jedra OS. Ta pristop razlikuje model sočasnosti GO in je ključni razlog, da so kanali učinkovite in preproste za uporabo z vidika programerja.