Middle
Aké typy mutexov poskytuje štandardná knižnica Go?
sobes.tech AI
Odpoveď od AI
Štandardná knižnica jazyka Go poskytuje dva hlavné typy zámkov v balíku sync:
sync.Mutex: Základný zámok, ktorý zabezpečuje vzájomné vylúčenie. Môže byť v dvoch stavoch: zamknutý alebo odomknutý. Len jedna gorutina môže držať zámok naraz.sync.RWMutex: Zámok pre čítanie/zápis. Umožňuje viacerým gorutinám súčasne čítať dáta (pomocouRLock), ale len jednej zapisovať (pomocouLock). Zápis blokuje všetky operácie (ako čítanie, tak zápis).
Hlavné metódy sync.Mutex:
| Metóda | Popis |
|---|---|
Lock() |
Zamkne zámok. Ak je už zamknutý, volajúca gorutina čaká na jeho odomknutie. |
Unlock() |
Odomkne zámok. Vyvolá sa panic, ak zámok nebol zamknutý volajúcou gorutinou. |
Hlavné metódy sync.RWMutex:
| Metóda | Popis |
|---|---|
Lock() |
Zamkne zámok pre zápis. Blokuje všetky operácie čítania aj zápisu. |
Unlock() |
Odomkne zámok pre zápis. Vyvolá sa panic, ak nebol zamknutý pre zápis. |
RLock() |
Zamkne zámok pre čítanie. Neblokuje iné operácie pre čítanie. Blokuje, ak je zamknutý pre zápis. |
RUnlock() |
Odomkne zámok pre čítanie. Vyvolá sa panic, ak nebol zamknutý pre čítanie. |
RLocker() |
Vráti Locker, ktorý používa RLock a RUnlock. |
Príklad použitia sync.Mutex:
package main
import (
"fmt"
"sync"
"time"
)
var counter int
var mutex sync.Mutex
func increment() {
mutex.Lock() // Zamkneme zámok
counter++
fmt.Printf("Counter: %d\n", counter)
mutex.Unlock() // Odblokujeme zámok
}
func main() {
for i := 0; i < 10; i++ {
go increment()
}
time.Sleep(time.Second) // Čakáme na dokončenie gorutín
}
Príklad použitia sync.RWMutex:
package main
import (
"fmt"
"sync"
"time"
)
var data string
var rwMutex sync.RWMutex
func readData() {
rwMutex.RLock() // Zamknutie pre čítanie
fmt.Printf("Čítanie dát: %s\n", data)
rwMutex.RUnlock() // Odblokovanie pre čítanie
}
func writeData(newData string) {
rwMutex.Lock() // Zamknutie pre zápis
data = newData
fmt.Printf("Zápis dát: %s\n", data)
rwMutex.Unlock() // Odblokovanie pre zápis
}
func main() {
go writeData("Hello")
time.Sleep(100 * time.Millisecond) // Čakáme na zápis
for i := 0; i < 5; i++ {
go readData() // Množstvo súčasných čítaní je povolené
}
time.Sleep(time.Second) // Čakáme na dokončenie gorutín
go writeData("World")
time.Sleep(100 * time.Millisecond)
go readData()
time.Sleep(time.Second)
}