మాడ్యూల్ పాఠాలు (4/5)
`sync.Mutex` మరియు `sync.WaitGroup`
ఛానెల్లు గో యొక్క ప్రాథమిక ఇడియమ్, కానీ కొన్నిసార్లు మరింత సాంప్రదాయంగా ఉంటాయి
ఆదిమానవులు కావాలి. sync ప్యాకేజీ మ్యూటెక్స్లను అందిస్తుంది, వేచి ఉండండి
భాగస్వామ్య స్థితిని సమన్వయం చేయడానికి సమూహాలు మరియు ఇతర వినియోగాలు.
sync.Mutex: ప్రత్యేకమైన లాక్
import "sync"
type Counter struct {
mu sync.Mutex
count int
}
func (c *Counter) Inc() {
c.mu.Lock()
defer c.mu.Unlock()
c.count++
}
func (c *Counter) Get() int {
c.mu.Lock()
defer c.mu.Unlock()
return c.count
}Lock() మరియు Unlock() మధ్య ఒకేసారి ఒక గోరౌటిన్ మాత్రమే ప్రవేశిస్తుంది.
తప్పనిసరి నమూనా: defer mu.Unlock() Lock() తర్వాత.
sync.RWMutex: చాలా మంది పాఠకులు, ఒక రచయిత
రీడ్-హెవీ స్టేట్ కోసం:
var mu sync.RWMutex
mu.RLock() // read lock: più goroutine simultanee OK
v := data
mu.RUnlock()
mu.Lock() // write lock: esclusivo
data = newValue
mu.Unlock()వ్రాతలపై చదవడం నిజంగా ఆధిపత్యం చెలాయిస్తే మాత్రమే ఉపయోగకరంగా ఉంటుంది; లేకపోతే రెగ్యులర్
sync.Mutex సరళమైనది మరియు తరచుగా వేగవంతమైనది తక్కువ అంతర్గత కారణంగా ధన్యవాదాలు
వివాదం.
sync.WaitGroup: N గోరౌటిన్ల కోసం వేచి ఉండండి
var wg sync.WaitGroup
for i := 0; i < 3; i++ {
wg.Add(1)
go func(id int) {
defer wg.Done()
work(id)
}(i)
}
wg.Wait() // blocca finché tutti i Done() sono arrivatiవర్క్ఫ్లో:
wg.Add(N)కౌంటర్ని N ద్వారా పెంచుతుంది (గోరౌటిన్లను ప్రారంభించే ముందు).- ప్రతి గోరూటిన్ అది ముగిసినప్పుడు
wg.Done()కి కాల్ చేస్తుంది (ఆదర్శంగాdeferద్వారా). - కౌంటర్ 0కి తిరిగి వెళ్లే వరకు
wg.Wait()బ్లాక్లు.
sync.Once: థ్రెడ్-సేఫ్ లేజీ ఇనిషియలైజేషన్
var (
once sync.Once
config *Config
)
func GetConfig() *Config {
once.Do(func() {
config = loadConfig()
})
return config
}once.Doలోని కాల్బ్యాక్ ఏకకాలంలో కూడా సరిగ్గా ఒకసారి నడుస్తుంది
కాల్స్. సింగిల్టన్ / సోమరితనం ప్రారంభ నమూనా.
Mutex vs ఛానెల్: ఎప్పుడు ఏమి ఉపయోగించాలి
మార్గదర్శకాలు (అధికారిక Go FAQ నుండి కూడా):
| కేసు | ఇష్టపడే సాధనం |
|---|---|
| డేటా యాజమాన్యాన్ని దాటుతోంది | ఛానెల్ |
| పనిని పంపిణీ చేస్తోంది (పని క్యూ) | ఛానెల్ |
| స్వతంత్ర గోరౌటిన్లను సమన్వయం చేయడం | ఛానెల్ |
| struct ఫీల్డ్ను రక్షించడం | మ్యూటెక్స్ |
| కాష్ / కౌంటర్ | మ్యూటెక్స్ లేదా పరమాణు |
| సింగిల్టన్ సూచన | sync.Once |
"ఆర్కెస్ట్రేట్ చేయడానికి ఛానెల్లు, షేర్డ్ డేటా కోసం మ్యూటెక్స్" అనేది మంచి నియమం.
రేస్ డిటెక్టర్
డేటా రేసులను గుర్తించడానికి -raceతో పరీక్షలను అమలు చేయండి:
go test -race ./...
go run -race main.goరేస్ డిటెక్టర్ బైనరీని సాధన చేస్తుంది మరియు సమకాలీకరించని ప్రతిదాన్ని లాగ్ చేస్తుంది షేర్డ్ మెమరీకి యాక్సెస్. ఇది ఏకకాల కోడ్ని ధృవీకరించడానికి సాధనం #1 ఉత్పత్తికి ముందు.
దీనిని ప్రయత్నించండి
mu.Lock() + defer mu.Unlock()తో కౌంట్ ఇంక్రిమెంట్ని రక్షించండి.
సూచనను చూపించు
ము. అన్లాక్()ని లాక్() తర్వాత భయాందోళనలో కూడా విడుదలకు హామీ ఇస్తుంది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
3 గోరౌటీన్లను ప్రారంభించండి మరియు సింక్ని ఉపయోగించి వాటన్నింటి కోసం వేచి ఉండండి.ప్రతి గోరౌటిన్లో వెయిట్గ్రూప్ (జోడించు(3), పూర్తయింది(), వేచి ఉండండి()).
సూచనను చూపించు
గోరూటిన్ను ప్రారంభించే ముందు జోడించండి; వాయిదాతో గోరూటిన్ లోపల పూర్తయింది.
3 ప్రయత్నాల తర్వాత పరిష్కారం లభిస్తుంది
మ్యూటెక్స్ విడుదల చేయబడిందని హామీ ఇవ్వడానికి సిఫార్సు చేయబడిన నమూనా ఏమిటి?
mu.Lock()
// ?రీక్యాప్
sync.Mutexభాగస్వామ్య స్థితిని రక్షిస్తుంది; ఎల్లప్పుడూdefer mu.Unlock().- మ్యూటెక్స్ని కాపీ చేయకుండా ఉండటానికి పాయింటర్ రిసీవర్ని ఉపయోగించండి.
sync.RWMutexఅనేక-పాఠకులు/ఒక-రచయిత నమూనాల కోసం (ఇది సహాయం చేస్తే మాత్రమే).sync.WaitGroup:Addముందుgo,Doneతోdefer,Waitవేచి ఉండండి.sync.Once: థ్రెడ్-సేఫ్ లేజీ ఇనిషియలైజేషన్.- "ఆర్కెస్ట్రేట్ చేయడానికి ఛానెల్లు, షేర్డ్ డేటా కోసం మ్యూటెక్స్".
go test -race: డేటా రేసులను గుర్తించడానికి సాధనం #1.