Middle
Jaké typy mutexů poskytuje standardní knihovna Go?
sobes.tech AI
Odpověď od AI
Standardní knihovna Go poskytuje dva hlavní typy zámků v balíčku sync:
sync.Mutex: Základní zámek, který zajišťuje vzájemné vyloučení. Může být ve dvou stavech: zamčený nebo odemčený. Pouze jedna gorutina může současně držet zámek.sync.RWMutex: Zámek pro čtení/zápis. Umožňuje více gorutinám současně číst data (pomocíRLock), ale pouze jedné zapisovat (pomocíLock). Zápis blokuje všechny operace (čtení i zápis).
Hlavní metody sync.Mutex:
| Metoda | Popis |
|---|---|
Lock() |
Zamkne zámek. Pokud je již zamčený, volající gorutina čeká na odemčení. |
Unlock() |
Odemyká zámek. Vyvolá se panic, pokud zámek nebyl zamčený volající gorutinou. |
Hlavní metody sync.RWMutex:
| Metoda | Popis |
|---|---|
Lock() |
Zamkne zámek pro zápis. Blokuje všechny operace čtení i zápisu. |
Unlock() |
Odemyká zámek pro zápis. Vyvolá se panic, pokud zámek nebyl zamčený pro zápis. |
RLock() |
Zamkne zámek pro čtení. Neblokuje jiné operace čtení. Blokuje, pokud je zámek zamčený pro zápis. |
RUnlock() |
Odemyká zámek pro čtení. Vyvolá se panic, pokud zámek nebyl zamčený pro čtení. |
RLocker() |
Vrací Locker, který používá RLock a RUnlock. |
Příklad použití sync.Mutex:
package main
import (
"fmt"
"sync"
"time"
)
var counter int
var mutex sync.Mutex
func increment() {
mutex.Lock() // Zamknutí zámku
counter++
fmt.Printf("Counter: %d\n", counter)
mutex.Unlock() // Odemykání zámku
}
func main() {
for i := 0; i < 10; i++ {
go increment()
}
time.Sleep(time.Second) // Čekáme na dokončení gorutin
}
Příklad použití sync.RWMutex:
package main
import (
"fmt"
"sync"
"time"
)
var data string
var rwMutex sync.RWMutex
func readData() {
rwMutex.RLock() // Zamknutí pro čtení
fmt.Printf("Čtení dat: %s\n", data)
rwMutex.RUnlock() // Odemykání pro čtení
}
func writeData(newData string) {
rwMutex.Lock() // Zamknutí pro zápis
data = newData
fmt.Printf("Zápis dat: %s\n", data)
rwMutex.Unlock() // Odemykání pro zápis
}
func main() {
go writeData("Hello")
time.Sleep(100 * time.Millisecond) // Čekáme na zápis
for i := 0; i < 5; i++ {
go readData() // Více současných čtení je povoleno
}
time.Sleep(time.Second) // Čekáme na dokončení gorutin
go writeData("World")
time.Sleep(100 * time.Millisecond)
go readData()
time.Sleep(time.Second)
}