Middle
Jakie typy mutexów zapewnia standardowa biblioteka Go?
sobes.tech AI
Odpowiedź od AI
Standardowa biblioteka Go zapewnia dwa główne typy mutexów w pakiecie sync:
sync.Mutex: Podstawowy mutex zapewniający wykluczenie wzajemne. Może być w dwóch stanach: zablokowany lub odblokowany. Tylko jedna gorutyna może utrzymywać blokadę w danym momencie.sync.RWMutex: Mutex do odczytu/zapisu. Pozwala wielu gorutynom odczytywać dane jednocześnie (poprzezRLock), ale tylko jednej na zapis (poprzezLock). Zapis blokuje wszystkie operacje (zarówno odczyt, jak i zapis).
Główne metody sync.Mutex:
| Metoda | Opis |
|---|---|
Lock() |
Blokuje mutex. Jeśli jest już zablokowany, wywołująca gorutyna zostaje zablokowana do czasu odblokowania. |
Unlock() |
Odblokowuje mutex. Panika, jeśli mutex nie był zablokowany przez wywołującą gorutynę. |
Główne metody sync.RWMutex:
| Metoda | Opis |
|---|---|
Lock() |
Blokuje mutex do zapisu. Blokuje wszystkie operacje odczytu i zapisu. |
Unlock() |
Odblokowuje mutex do zapisu. Panika, jeśli mutex nie był zablokowany do zapisu. |
RLock() |
Blokuje mutex do odczytu. Nie blokuje innych operacji odczytu. Zablokuje się, jeśli istnieje blokada zapisu. |
RUnlock() |
Odblokowuje mutex do odczytu. Panika, jeśli mutex nie był zablokowany do odczytu. |
RLocker() |
Zwraca Locker, który używa RLock i RUnlock. |
Przykład użycia sync.Mutex:
package main
import (
"fmt"
"sync"
"time"
)
var counter int
var mutex sync.Mutex
func increment() {
mutex.Lock() // Blokuje mutex
counter++
fmt.Printf("Counter: %d\n", counter)
mutex.Unlock() // Odblokowuje mutex
}
func main() {
for i := 0; i < 10; i++ {
go increment()
}
time.Sleep(time.Second) // Daje czas gorutynom na zakończenie
}
Przykład użycia sync.RWMutex:
package main
import (
"fmt"
"sync"
"time"
)
var data string
var rwMutex sync.RWMutex
func readData() {
rwMutex.RLock() // Blokuje do odczytu
fmt.Printf("Odczyt danych: %s\n", data)
rwMutex.RUnlock() // Odblokowuje do odczytu
}
func writeData(newData string) {
rwMutex.Lock() // Blokuje do zapisu
data = newData
fmt.Printf("Zapis danych: %s\n", data)
rwMutex.Unlock() // Odblokowuje do zapisu
}
func main() {
go writeData("Cześć")
time.Sleep(100 * time.Millisecond) // Daje czas na zapis
for i := 0; i < 5; i++ {
go readData() // Dozwolone wiele równoczesnych odczytów
}
time.Sleep(time.Second) // Daje czas na zakończenie gorutyn
go writeData("Świat")
time.Sleep(100 * time.Millisecond)
go readData()
time.Sleep(time.Second)
}