ప్రధాన కంటెంట్‌కు వెళ్లండి
మాడ్యూల్ 7 · 5లో పాఠం 2కోర్సులో 32/50~15 min
మాడ్యూల్ పాఠాలు (2/5)

ఛానెల్‌లు: టైప్ చేసిన కమ్యూనికేషన్

ఛానెల్స్ మధ్య కమ్యూనికేషన్ కోసం ఇడియోమాటిక్ మెకానిజం గోరూటీన్లు. ది గో ఫిలాసఫీ (రాబ్ పైక్):

"మెమొరీని పంచుకోవడం ద్వారా కమ్యూనికేట్ చేయవద్దు; కమ్యూనికేట్ చేయడం ద్వారా మెమరీని పంచుకోండి."

ఛానెల్ అనేది టైప్ చేసిన FIFO క్యూ, టైప్-సురక్షితమైనది మరియు ఏకకాలంలో సురక్షితమైనది ఉపయోగించండి. goతో కలిపి, ఇది గో యొక్క ప్రాథమిక బిల్డింగ్ బ్లాక్ సమ్మతి.

సృష్టించండి, పంపండి, స్వీకరించండి

Go
ch := make(chan int)     // canale di int, unbuffered

go func() {
    ch <- 42             // invia (può bloccare)
}()

v := <-ch                // ricevi (può bloccare)
fmt.Println(v)           // 42

సింటాక్స్:

  • బఫర్ కోసం make(chan T) లేదా make(chan T, N).
  • ch <- v పంపుతుంది.
  • v := <-ch అందుకుంటుంది.
  • v, ok := <-ch ఫ్లాగ్‌తో అందుకుంటుంది (ok = false ఛానెల్ మూసివేయబడి ఖాళీగా ఉంటే).

బఫర్ చేయబడలేదు: రెండెజౌస్

బఫర్ చేయని ఛానెల్ (కెపాసిటీ 0) బ్లాక్ చేస్తుంది:

  • రిసీవర్ సిద్ధమయ్యే వరకు పంపినవారు;
  • పంపినవారు సిద్ధమయ్యే వరకు రిసీవర్.

ఇది సింక్రోనస్ అపాయింట్‌మెంట్: "సిగ్నల్"గా లేదా హామీకి ఉపయోగపడుతుంది విలువ పంపిణీ చేయబడింది.

బఫర్ చేయబడింది: N వరకు క్యూ

Go
ch := make(chan int, 3)
ch <- 1   // non blocca
ch <- 2   // non blocca
ch <- 3   // non blocca
ch <- 4   // BLOCCA: il buffer è pieno

బఫర్ నిండినప్పుడు మాత్రమే పంపినవారు బ్లాక్ చేస్తారు; రిసీవర్ మాత్రమే అది ఖాళీగా ఉన్నప్పుడు.

దగ్గరగా మరియు పరిధి కోసం

విలువలు లేనప్పుడు పంపినవారు ఛానెల్‌ని మూసివేస్తారు:

Go
ch := make(chan int, 3)
ch <- 1
ch <- 2
ch <- 3
close(ch)

for v := range ch {      // termina quando ch è chiuso E vuoto
    fmt.Println(v)
}

for range ఛానెల్ మూసివేయబడే వరకు (మరియు డ్రెయిన్ అయ్యే వరకు) ఛానెల్‌లో పునరావృతమవుతుంది. ఇది "వచ్చే ప్రతిదాన్ని వినియోగిస్తుంది" అనే పరిశుభ్రమైన నమూనా.

సంతకాలలో దిశాత్మకత

ఫంక్షన్ పారామితులు దిశను పరిమితం చేయవచ్చు:

Go
func producer(out chan<- int) {   // solo invio
    out <- 1
    close(out)
}

func consumer(in <-chan int) {    // solo ricezione
    for v := range in {
        fmt.Println(v)
    }
}

chan<- T = పంపడానికి మాత్రమే, <-chan T = స్వీకరించడానికి మాత్రమే. ఒక ద్విదిశాత్మక ఛానెల్ chan Tని దేనికైనా పంపవచ్చు (అవ్యక్త మార్పిడి). ఇది స్పష్టతను మెరుగుపరుస్తుంది మరియు తప్పులను నివారిస్తుంది.

సాధారణ నమూనాలు (ప్రివ్యూ)

  • వర్కర్ పూల్: N goroutines jobs <-chan T నుండి వినియోగిస్తుంది, results chan<- Rలో ఉత్పత్తి చేస్తుంది.
  • పైప్‌లైన్: ఛానెల్‌ల ద్వారా కనెక్ట్ చేయబడిన దశలు.
  • ** పూర్తయింది సిగ్నల్**: ఒక chan struct{} ఛానెల్ "స్టాప్" సిగ్నల్ కోసం మూసివేయబడింది.
Go
done := make(chan struct{})
go func() {
    <-done    // blocca finché qualcuno chiude done
    cleanup()
}()
close(done)   // segnale di stop

chan struct{} "సిగ్నల్" ఛానెల్: పేలోడ్ సున్నా బైట్‌లు, కేవలం సమకాలీకరణ.

దీనిని ప్రయత్నించండి

వ్యాయామం#go.m7.l2.e1
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

ఒక unbuffered int ఛానెల్ chని సృష్టించండి, గోరౌటిన్ నుండి 42 పంపండి, మెయిన్‌లో స్వీకరించండి మరియు దానిని ప్రింట్ చేయండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

బఫర్ లేకుండా, పంపినవారు మరియు రిసీవర్ సమకాలీకరించబడతాయి.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

వ్యాయామం#go.m7.l2.e2
ప్రయత్నాలు: 0లోడ్ అవుతోంది...

బఫర్ చేయబడిన ఛానెల్ ద్వారా 1,2,3ని పంపండి, దాన్ని మూసివేయండి, ఆపై ప్రతిదానిని పరిధి కోసం ప్రింట్ చేయండి.

ఎడిటర్ లోడ్ అవుతోంది…
సూచనను చూపించు

ఛానెల్ మూసివేయబడినప్పుడు మరియు డ్రైనేజ్ అయినప్పుడు ఛానెల్‌పై `పరిధి కోసం` ముగుస్తుంది.

3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది

Quiz#go.m7.l2.e3
సిద్ధంగా ఉంది

పంపినవారు పంపినప్పుడు కానీ రిసీవర్ సిద్ధంగా లేనప్పుడు UNBUFFERED ఛానెల్ ఏమి చేస్తుంది?

Go
ch := make(chan int)
ch <- 1 // ?
సమాధాన ఎంపికలు

రీక్యాప్

  • ఛానెల్ = టైప్ చేసిన FIFO క్యూ, గోరౌటిన్‌ల మధ్య సురక్షితం.
  • బఫర్ చేయబడలేదు: రెండెజౌస్ (పంపినవారు మరియు రిసీవర్ సమకాలీకరించడం).
  • బఫర్ చేయబడింది: డీకప్లింగ్, పూర్తిగా/ఖాళీగా ఉన్నప్పుడు మాత్రమే బ్లాక్ చేస్తుంది.
  • close(ch): పంపినవారు మాత్రమే; for range మూసివేయబడే వరకు వినియోగిస్తుంది.
  • దిశాత్మకత: chan<- T (పంపడానికి మాత్రమే), <-chan T (స్వీకరించడానికి మాత్రమే).
  • chan struct{} స్వచ్ఛమైన సమకాలీకరణ కోసం సిగ్నల్ ఛానెల్‌గా.