რა არის მუტექსი, რა ტიპის მუტექსები არსებობს და როგორ გამოიყენოთ ისინი?
sobes.tech AI
პასუხი AI-სგან
Մյուտեքս (անգլ. MUTual EXclusion) — դա սինխրոնիզացիայի primitives է, որը օգտագործվում է բաժանվող ռեսուրսի բացառիկ մուտքը ապահովելու համար մրցակցող գորուտինների միջև։ Այն երաշխավորում է, որ ցանկացած պահի միայն մեկ գորուտին կարող է տիրապետել մյուտեքսին և համապատասխանաբար մուտք գործել պաշտպանված տվյալները։
Go-ում sync փաթեթը տրամադրում է երկու հիմնական մյուտեքսների տեսակներ՝
-
sync.Mutex: Ստանդարտ մյուտեքս։ Պատրաստում էLock()ևUnlock()մեթոդներ։ Եթե մյուտեքսը արդեն փակ է,Lock()կանչը բլոկավորում է ընթացիկ գորուտինին մինչև այն բացվի։Unlock()բացում է մյուտեքսը։var mu sync.Mutex var counter int func increment() { mu.Lock() // Բլոկավորում մուտքը counter-ին counter++ mu.Unlock() // Բացում մուտքը } -
sync.RWMutex: Մյուտեքս ընթերցման/գրելու համար։ Ինքը թույլ է տալիս միաժամանակ մի քանի գորուտինների ընթերցել պաշտպանված ռեսուրսը, բայց միայն մեկին գրել։ Պատրաստում էLock(),Unlock()(գրելու համար),RLock()ևRUnlock()(ընթերցման համար) մեթոդներ։var rwMu sync.RWMutex var data []int func readData() { rwMu.RLock() // Բլոկավորում ընթերցման համար // Կարդում data fmt.Println(data) rwMu.RUnlock() // Բացում ընթերցումը } func writeData(val int) { rwMu.Lock() // Բլոկավորում գրելու համար // Գրանցում data-ում data = append(data, val) rwMu.Unlock() // Բացում գրառումը }
Մյուտեքսների օգտագործումը անհրաժեշտ է ռասային պայմանների կանխարգելման համար, երբ միաժամանակ մի քանի գորուտիններ փորձում են փոփոխել նույն տվյալները, ինչը կարող է հանգեցնել անսպասելի արդյունքների։
Օգտագործման կանոններ՝
- Կոչել
Lock()՝ պաշտպանված ռեսուրսին մուտք գործելուց առաջ։ - Կոչել
Unlock()՝ մուտքի ավարտից հետո։ Առաջարկվում է օգտագործելdefer mu.Unlock()՝ բացելու համար նույնիսկ պանիկի դեպքում։ - Չի կարելի կրկին փակել արդեն փակ մյուտեքսը նույն գորուտինից։
- Չի կարելի բացել անփակ մյուտեքսը։
- Երբ օգտագործում եք
RWMutex, օգտագործեքRLock()/RUnlock()ընթերցման համար ևLock()/Unlock()գրելու համար։ - Մյուտեքսները չպետք է պատճենվեն առաջին օգտագործումից հետո։ Դրանք փոխանցվում են հղումով կամ ցուցիչով։
Օրինակ defer օգտագործման:
func safeIncrement() {
mu.Lock()
defer mu.Unlock() // Գаранտիա է բացումը
counter++
}