మాడ్యూల్ పాఠాలు (2/5)
ఛానెల్లు: టైప్ చేసిన కమ్యూనికేషన్
ఛానెల్స్ మధ్య కమ్యూనికేషన్ కోసం ఇడియోమాటిక్ మెకానిజం గోరూటీన్లు. ది గో ఫిలాసఫీ (రాబ్ పైక్):
"మెమొరీని పంచుకోవడం ద్వారా కమ్యూనికేట్ చేయవద్దు; కమ్యూనికేట్ చేయడం ద్వారా మెమరీని పంచుకోండి."
ఛానెల్ అనేది టైప్ చేసిన FIFO క్యూ, టైప్-సురక్షితమైనది మరియు ఏకకాలంలో సురక్షితమైనది
ఉపయోగించండి. 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 వరకు క్యూ
ch := make(chan int, 3)
ch <- 1 // non blocca
ch <- 2 // non blocca
ch <- 3 // non blocca
ch <- 4 // BLOCCA: il buffer è pienoబఫర్ నిండినప్పుడు మాత్రమే పంపినవారు బ్లాక్ చేస్తారు; రిసీవర్ మాత్రమే అది ఖాళీగా ఉన్నప్పుడు.
దగ్గరగా మరియు పరిధి కోసం
విలువలు లేనప్పుడు పంపినవారు ఛానెల్ని మూసివేస్తారు:
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 ఛానెల్ మూసివేయబడే వరకు (మరియు డ్రెయిన్ అయ్యే వరకు) ఛానెల్లో పునరావృతమవుతుంది.
ఇది "వచ్చే ప్రతిదాన్ని వినియోగిస్తుంది" అనే పరిశుభ్రమైన నమూనా.
సంతకాలలో దిశాత్మకత
ఫంక్షన్ పారామితులు దిశను పరిమితం చేయవచ్చు:
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{}ఛానెల్ "స్టాప్" సిగ్నల్ కోసం మూసివేయబడింది.
done := make(chan struct{})
go func() {
<-done // blocca finché qualcuno chiude done
cleanup()
}()
close(done) // segnale di stopchan struct{} "సిగ్నల్" ఛానెల్: పేలోడ్ సున్నా బైట్లు, కేవలం
సమకాలీకరణ.
దీనిని ప్రయత్నించండి
ఒక unbuffered int ఛానెల్ chని సృష్టించండి, గోరౌటిన్ నుండి 42 పంపండి, మెయిన్లో స్వీకరించండి మరియు దానిని ప్రింట్ చేయండి.
సూచనను చూపించు
బఫర్ లేకుండా, పంపినవారు మరియు రిసీవర్ సమకాలీకరించబడతాయి.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
బఫర్ చేయబడిన ఛానెల్ ద్వారా 1,2,3ని పంపండి, దాన్ని మూసివేయండి, ఆపై ప్రతిదానిని పరిధి కోసం ప్రింట్ చేయండి.
సూచనను చూపించు
ఛానెల్ మూసివేయబడినప్పుడు మరియు డ్రైనేజ్ అయినప్పుడు ఛానెల్పై `పరిధి కోసం` ముగుస్తుంది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
పంపినవారు పంపినప్పుడు కానీ రిసీవర్ సిద్ధంగా లేనప్పుడు UNBUFFERED ఛానెల్ ఏమి చేస్తుంది?
ch := make(chan int)
ch <- 1 // ?రీక్యాప్
- ఛానెల్ = టైప్ చేసిన FIFO క్యూ, గోరౌటిన్ల మధ్య సురక్షితం.
- బఫర్ చేయబడలేదు: రెండెజౌస్ (పంపినవారు మరియు రిసీవర్ సమకాలీకరించడం).
- బఫర్ చేయబడింది: డీకప్లింగ్, పూర్తిగా/ఖాళీగా ఉన్నప్పుడు మాత్రమే బ్లాక్ చేస్తుంది.
close(ch): పంపినవారు మాత్రమే;for rangeమూసివేయబడే వరకు వినియోగిస్తుంది.- దిశాత్మకత:
chan<- T(పంపడానికి మాత్రమే),<-chan T(స్వీకరించడానికి మాత్రమే). chan struct{}స్వచ్ఛమైన సమకాలీకరణ కోసం సిగ్నల్ ఛానెల్గా.