முக்கிய உள்ளடக்கத்திற்குச் செல்லவும்
தொகுதி 7 · பாடம் 4 இன் 5பாடத்திட்டத்தில் 34/50~14 min
தொகுதி பாடங்கள் (4/5)

`sync.Mutex` மற்றும் `sync.WaitGroup`

சேனல்கள் கோவின் முதன்மையான மொழியாகும், ஆனால் சில சமயங்களில் மிகவும் பாரம்பரியமானது பழமையானவை தேவை. sync தொகுப்பு மியூடெக்ஸ்களை வழங்குகிறது, காத்திருக்கவும் பகிரப்பட்ட மாநிலத்தை ஒருங்கிணைக்க குழுக்கள் மற்றும் பிற பயன்பாடுகள்.

sync.Mutex: பிரத்தியேக பூட்டு

Go
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: பல வாசகர்கள், ஒரு எழுத்தாளர்

படிக்க-கடுமையான நிலைக்கு:

Go
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 க்காக காத்திருங்கள்

Go
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

பணிப்பாய்வு:

  1. wg.Add(N) கவுண்டரை N ஆல் அதிகரிக்கிறது (கோரூட்டீன்களைத் தொடங்குவதற்கு முன்).
  2. ஒவ்வொரு goroutine அது முடிந்ததும் wg.Done() ஐ அழைக்கிறது (மிகவும் defer வழியாக).
  3. கவுண்டர் 0க்கு திரும்பும் வரை wg.Wait() தடுக்கிறது.

ஒத்திசைவு.ஒருமுறை: நூல்-பாதுகாப்பான சோம்பேறி துவக்கம்

Go
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 உடன் சோதனைகளை இயக்கவும்:

Bash
go test -race ./...
go run -race main.go

ரேஸ் டிடெக்டர் பைனரியை கருவியாக்கி, ஒத்திசைக்கப்படாத ஒவ்வொன்றையும் பதிவு செய்கிறது பகிரப்பட்ட நினைவகத்திற்கான அணுகல். ஒரே நேரத்தில் குறியீட்டை சரிபார்க்க இது கருவி #1 ஆகும் உற்பத்திக்கு முன்.

முயற்சி செய்து பாருங்கள்

உடற்பயிற்சி#go.m7.l4.e1
முயற்சிகள்: 0ஏற்றுகிறது…

mu.Lock() + defer mu.Unlock() மூலம் எண்ணிக்கையின் அதிகரிப்பைப் பாதுகாக்கவும்.

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

மு. அன்லாக்() க்குப் பிறகு பூட்டு() பீதியில் கூட வெளியீட்டிற்கு உத்தரவாதம் அளிக்கிறது.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

உடற்பயிற்சி#go.m7.l4.e2
முயற்சிகள்: 0ஏற்றுகிறது…

3 goroutineகளைத் துவக்கி, அவை அனைத்திற்கும் ஒத்திசைவைப் பயன்படுத்தி காத்திருக்கவும்.WaitGroup (சேர்(3), முடிந்தது() ஒவ்வொரு goroutine லும், Wait()).

எடிட்டரை ஏற்றுகிறது…
குறிப்பைக் காட்டு

கோரூட்டினைத் தொடங்குவதற்கு முன் சேர்க்கவும்; ஒத்திவைப்புடன் goroutine இன் உள்ளே முடிந்தது.

3 முயற்சிகளுக்குப் பிறகு தீர்வு கிடைக்கும்

Quiz#go.m7.l4.e3
தயார்

மியூடெக்ஸ் வெளியிடப்படுவதற்கு உத்தரவாதம் அளிக்க பரிந்துரைக்கப்பட்ட முறை என்ன?

Go
mu.Lock()
// ?
பதில் விருப்பங்கள்

மறுபரிசீலனை

  • sync.Mutex பகிரப்பட்ட நிலையைப் பாதுகாக்கிறது; எப்போதும் defer mu.Unlock().
  • மியூடெக்ஸை நகலெடுப்பதைத் தவிர்க்க சுட்டி ரிசீவரை பயன்படுத்தவும்.
  • sync.RWMutex பல வாசகர்கள்/ஒருவர் எழுதும் வடிவங்களுக்கு (அது உதவினால் மட்டும்).
  • sync.WaitGroup: Add goக்கு முன், Done உடன் defer, Wait காத்திருக்க.
  • sync.Once: நூல்-பாதுகாப்பான சோம்பேறி துவக்கம்.
  • "ஆர்கெஸ்ட்ரேட் செய்வதற்கான சேனல்கள், பகிரப்பட்ட தரவுகளுக்கான மியூடெக்ஸ்கள்".
  • go test -race: தரவு பந்தயங்களைக் கண்டறிய கருவி #1.