మాడ్యూల్ పాఠాలు (3/5)
`సెలెక్ట్`: మల్టీప్లెక్సింగ్ ఛానెల్లు
select ఒకే సమయంలో బహుళ ఛానెల్ కార్యకలాపాలలో వేచి ఉంది.
ఇది switch గో కాన్కరెన్సీ: ఇది మిమ్మల్ని మొదటి దానికి ప్రతిస్పందించడానికి అనుమతిస్తుంది
చాలా మందిలో ఛానెల్ సిద్ధంగా ఉంది.
వాక్యనిర్మాణం
select {
case v := <-ch1:
fmt.Println("ch1:", v)
case v := <-ch2:
fmt.Println("ch2:", v)
case ch3 <- 99:
fmt.Println("inviato su ch3")
case <-time.After(time.Second):
fmt.Println("timeout")
default:
fmt.Println("nessuno è pronto")
}అర్థశాస్త్రం:
- అన్ని కేసులు మూల్యాంకనం చేయబడతాయి; ** సిద్ధంగా ఉన్న కేసులలో ఒకటి మాత్రమే ఎంపిక చేయబడింది.
- బహుళ కేసులు సిద్ధంగా ఉంటే, ఎంపిక సూడో-యాదృచ్ఛికం (ఆర్డరింగ్ లేదు).
- ఏ కేసు కూడా సిద్ధంగా లేకుంటే: ఒకటి సిద్ధమయ్యే వరకు
selectబ్లాక్ అవుతుంది. defaultఉన్నట్లయితే: ఏ కేసు కూడా సిద్ధంగా లేనప్పుడు అది వెంటనే నడుస్తుంది (నాన్-బ్లాకింగ్ ఎంచుకోండి).
గడువు ముగిసిన నమూనా
select {
case res := <-fetch(url):
use(res)
case <-time.After(2 * time.Second):
log.Println("timeout: fetch troppo lento")
}time.After(d) d తర్వాత విలువను ఉత్పత్తి చేసే <-chan Timeని అందిస్తుంది.
నిరీక్షణను కట్టడి చేయడానికి ఇది క్లాసిక్ మార్గం.
నాన్-బ్లాకింగ్ డిఫాల్ట్తో ఎంచుకోండి
select {
case msg := <-ch:
process(msg)
default:
// niente da fare, prosegui
}ఇది ఛానెల్ని బ్లాక్ చేయకుండా "పోల్" చేస్తుంది. కోడ్ పాత్లలో ఉపయోగపడుతుంది తప్పనిసరిగా వేచి ఉండకుండా ప్రతిస్పందిస్తూ ఉండాలి.
"పూర్తయిన ఛానెల్" నమూనా
రద్దు ఛానెల్తో selectని కలపండి:
func worker(in <-chan Job, done <-chan struct{}) {
for {
select {
case j := <-in:
process(j)
case <-done:
return // chi gestisce done segnala lo shutdown
}
}
}కోఆర్డినేటర్ నుండి close(done) ప్రతిదానిలో case <-doneని ట్రిగ్గర్ చేస్తుంది
నిరీక్షణ గోరూటిన్: సమన్వయ షట్డౌన్.
ఎంపికతో లూప్ చేయండి
for {
select {
case v := <-input:
if v == nil {
return
}
handle(v)
case <-time.After(5 * time.Second):
keepAlive()
case <-ctx.Done():
return
}
}సర్వర్లు మరియు కార్మికుల కోసం సాధారణ "ఈవెంట్ లూప్" నమూనా.
"డిసేబుల్" కేస్గా నిల్ ఛానెల్
అధునాతన ట్రిక్: case <-chతో ch == nil ఎప్పటికీ
ఎంపిక చేయబడింది. ఇది డైనమిక్గా కేసును "డిసేబుల్" చేయడానికి మిమ్మల్ని అనుమతిస్తుంది:
var in chan int = source()
for {
select {
case v, ok := <-in:
if !ok {
in = nil // disabilita questo case
continue
}
handle(v)
case <-ctx.Done():
return
}
}in మూసివేయబడినప్పుడు, నేను దానిని రద్దు చేస్తాను: select మాత్రమే నిర్వహిస్తుంది
ఇతర కేసులు.
దీనిని ప్రయత్నించండి
ch1 మరియు ch2 నుండి స్వీకరించే రెండు కేసులతో ఎంపికను అమలు చేయండి; ముందుగా వచ్చిన దానిని ప్రింట్ చేయండి.
సూచనను చూపించు
సింటాక్స్ `సెలెక్ట్ { కేస్ ...: ... }` ఒక్కో ఛానెల్కు ఒక కేస్తో.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
సమయాన్ని ఉపయోగించి ఎంపికకు గడువు ముగిసిన సందర్భాన్ని జోడించండి.ఆఫ్టర్(సమయం.సెకండ్).
సూచనను చూపించు
`time.After(d)` అనేది d తర్వాత స్వీకరించే ఛానెల్.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
ఎంచుకున్న నాన్-బ్లాకింగ్ ఏమి చేస్తుంది?
select { case v := <-ch: ... ??? }రీక్యాప్
selectఅనేక ఛానెల్ కార్యకలాపాలలో మొదటి సిద్ధంగా ఉన్న కేసు కోసం వేచి ఉంది.- బహుళ సిద్ధంగా ఉన్న కేసులలో సూడో-యాదృచ్ఛిక ఎంపిక.
default→ నాన్-బ్లాకింగ్ ఎంపిక (పోలింగ్).time.After(d)గడువు ముగిసింది (లూప్లలో లీక్ని గుర్తుంచుకోండి:contextని ఉపయోగించండి).- నమూనాలు: ఒక కేసును నిలిపివేయడానికి ఛానెల్, ఈవెంట్ లూప్, నిల్ ఛానెల్.
- ఖాళీ
select{}= ఎటర్నల్ బ్లాక్: దాదాపు ఎల్లప్పుడూ బగ్.