தொகுதி பாடங்கள் (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 goroutines க்காக காத்திருங்கள்
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 ஆல் அதிகரிக்கிறது (கோரூட்டீன்களைத் தொடங்குவதற்கு முன்).- ஒவ்வொரு goroutine அது முடிந்ததும்
wg.Done()ஐ அழைக்கிறது (மிகவும்deferவழியாக). - கவுண்டர் 0க்கு திரும்பும் வரை
wg.Wait()தடுக்கிறது.
ஒத்திசைவு.ஒருமுறை: நூல்-பாதுகாப்பான சோம்பேறி துவக்கம்
var (
once sync.Once
config *Config
)
func GetConfig() *Config {
once.Do(func() {
config = loadConfig()
})
return config
}once.Do இல் உள்ள கால்பேக் சரியாக ஒருமுறை, ஒரே நேரத்தில் கூட இயங்கும்
அழைப்புகள். சிங்கிள்டன் / சோம்பேறி துவக்க முறை.
மியூடெக்ஸ் vs சேனல்: எதை எப்போது பயன்படுத்த வேண்டும்
வழிகாட்டுதல்கள் (அதிகாரப்பூர்வ Go FAQ இலிருந்தும்):
| வழக்கு | விருப்பமான கருவி |
|---|---|
| தரவு உரிமையை கடந்து செல்கிறது | சேனல் |
| வேலைகளை விநியோகித்தல் (வேலை வரிசை) | சேனல் |
| சுயாதீன goroutines ஒருங்கிணைத்தல் | சேனல் |
| ஒரு struct புலத்தை பாதுகாத்தல் | Mutex |
| கேச் / கவுண்டர் | Mutex அல்லது அணு |
| சிங்கிள்டன் குறிப்பு | sync.Once |
"ஆர்கெஸ்ட்ரேட் செய்வதற்கான சேனல்கள், பகிரப்பட்ட தரவுகளுக்கான மியூடெக்ஸ்கள்" என்பது ஒரு நல்ல கட்டைவிரல் விதி.
ரேஸ் டிடெக்டர்
தரவு பந்தயங்களைக் கண்டறிய -race உடன் சோதனைகளை இயக்கவும்:
go test -race ./...
go run -race main.goரேஸ் டிடெக்டர் பைனரியை கருவியாக்கி, ஒத்திசைக்கப்படாத ஒவ்வொன்றையும் பதிவு செய்கிறது பகிரப்பட்ட நினைவகத்திற்கான அணுகல். ஒரே நேரத்தில் குறியீட்டை சரிபார்க்க இது கருவி #1 ஆகும் உற்பத்திக்கு முன்.
முயற்சி செய்து பாருங்கள்
mu.Lock() + defer mu.Unlock() மூலம் எண்ணிக்கையின் அதிகரிப்பைப் பாதுகாக்கவும்.
குறிப்பைக் காட்டு
மு. அன்லாக்() க்குப் பிறகு பூட்டு() பீதியில் கூட வெளியீட்டிற்கு உத்தரவாதம் அளிக்கிறது.
3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்
3 goroutineகளைத் துவக்கி, அவை அனைத்திற்கும் ஒத்திசைவைப் பயன்படுத்தி காத்திருக்கவும்.WaitGroup (சேர்(3), முடிந்தது() ஒவ்வொரு goroutine லும், Wait()).
குறிப்பைக் காட்டு
கோரூட்டினைத் தொடங்குவதற்கு முன் சேர்க்கவும்; ஒத்திவைப்புடன் goroutine இன் உள்ளே முடிந்தது.
3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்
மியூடெக்ஸ் வெளியிடப்படுவதற்கு உத்தரவாதம் அளிக்க பரிந்துரைக்கப்பட்ட முறை என்ன?
mu.Lock()
// ?மறுபரிசீலனை
sync.Mutexபகிரப்பட்ட நிலையைப் பாதுகாக்கிறது; எப்போதும்defer mu.Unlock().- மியூடெக்ஸை நகலெடுப்பதைத் தவிர்க்க சுட்டி ரிசீவரை பயன்படுத்தவும்.
sync.RWMutexபல வாசகர்கள்/ஒருவர் எழுதும் வடிவங்களுக்கு (அது உதவினால் மட்டும்).sync.WaitGroup:Addgoக்கு முன்,Doneஉடன்defer,Waitகாத்திருக்க.sync.Once: நூல்-பாதுகாப்பான சோம்பேறி துவக்கம்.- "ஆர்கெஸ்ட்ரேட் செய்வதற்கான சேனல்கள், பகிரப்பட்ட தரவுகளுக்கான மியூடெக்ஸ்கள்".
go test -race: தரவு பந்தயங்களைக் கண்டறிய கருவி #1.