sync.Mutex i sync.RWMutex
Wzorce blokad oraz blokad odczytu i zapisu
sync.Mutex i sync.RWMutex to bezpłatna lekcja Go Academy na CoddyKit. To lekcja 1 z 4. Możesz przeczytać całą lekcję poniżej za darmo — a potem ćwiczyć ją interaktywnie w przeglądarce z wbudowanym edytorem kodu i tutorem AI dostępnym 24/7. To część ścieżki edukacyjnej Go Academy, a Twój postęp synchronizuje się między webem a aplikacją CoddyKit. Kurs Go Academy zawiera 4 lekcji w sumie.
Dlaczego muteksy?
Gdy wiele gorutyn współdzieli zmienny stan, równoczesne odczyty i zapisy powodują wyścigi danych. Mutex szeregowo porządkuje dostęp, dzięki czemu w danej chwili tylko jedna gorutyna wchodzi do sekcji krytycznej.
Podstawy sync.Mutex
Przed odczytem lub zapisem współdzielonego stanu należy wywołać Lock, a po nim Unlock. Należy użyć defer, aby zagwarantować odblokowanie nawet wtedy, gdy funkcja wywoła panic.
var mu sync.Mutex
var counter int
func inc() {
mu.Lock()
defer mu.Unlock()
counter++
}Osadzanie Mutex w strukturze
Mutex należy osadzić w strukturze, którą chroni. Zgodnie z przyjętą konwencją mutex deklaruje się bezpośrednio nad polami, które chroni.
type SafeCounter struct {
mu sync.Mutex
v map[string]int
}
func (c *SafeCounter) Inc(key string) {
c.mu.Lock()
defer c.mu.Unlock()
c.v[key]++
}Nie należy kopiować Mutex
Mutex nie wolno kopiować po pierwszym użyciu. Należy przekazywać go przez wskaźnik albo osadzić w strukturze przekazywanej przez wskaźnik. Narzędzie go vet wykrywa kopie.
sync.RWMutex
sync.RWMutex pozwala wielu czytelnikom działać współbieżnie, ale dopuszcza tylko jednego autora. Należy go używać, gdy odczyty dominują, a zapisy są rzadkie, aby zwiększyć przepustowość.
var rw sync.RWMutex
var data map[string]int
func read(k string) int {
rw.RLock()
defer rw.RUnlock()
return data[k]
}
func write(k string, v int) {
rw.Lock()
defer rw.Unlock()
data[k] = v
}RLock a Lock
RLock uzyskuje blokadę odczytu (współdzieloną), a Lock uzyskuje blokadę zapisu (wyłączną). Oczekująca blokada zapisu blokuje nowe blokady odczytu, zapobiegając zagłodzeniu autora.
TryLock (Go 1.18+)
mu.TryLock() uzyskuje blokadę tylko wtedy, gdy nie jest ona obecnie zajęta, i zwraca wartość logiczną. Jest przydatny, gdy blokowanie jest niedopuszczalne.
if mu.TryLock() {
defer mu.Unlock()
// critical section
}Zakleszczenia
Zakleszczenie występuje, gdy gorutyna A posiada blokadę 1 i czeka na blokadę 2, a gorutyna B posiada blokadę 2 i czeka na blokadę 1. Zawsze należy uzyskiwać blokady w tej samej kolejności i utrzymywać sekcje krytyczne w krótkim czasie.
Ziarnistość blokad
Blokada gruboziarnista jest łatwiejsza do analizowania, ale ogranicza współbieżność. Blokady drobnoziarniste zwiększają przepustowość, lecz podnoszą złożoność i ryzyko zakleszczeń. Należy zacząć od blokady gruboziarnistej i optymalizować dopiero wtedy, gdy profilowanie wykaże rywalizację o zasoby.
Mutex a kanał
Mutex należy stosować do ochrony współdzielonego stanu, z którym pracuje wielu czytelników i autorów. Kanału należy używać do przekazywania własności danych między gorutynami. Kanały służą do komunikacji, a muteksy do synchronizacji.
Interfejs sync.Locker
sync.Locker to interfejs zawierający Lock i Unlock. Zarówno Mutex, jak i RWMutex go implementują, dzięki czemu funkcje pomocnicze mogą przyjmować dowolny z tych typów.
Szybki test
Kiedy należy użyć sync.RWMutex zamiast sync.Mutex?
Podsumowanie: Mutex i RWMutex
Najważniejsze informacje:
- Mutex serializuje dostęp; zawsze wywołuj Unlock za pomocą defer
- Nie kopiuj Mutex po pierwszym użyciu
- RWMutex: wielu czytelników LUB jeden zapisujący
- Blokady należy uzyskiwać w spójnej kolejności, aby uniknąć zakleszczeń
Często zadawane pytania
Czy lekcja „sync.Mutex i sync.RWMutex” jest bezpłatna?
Tak — pełny tekst „sync.Mutex i sync.RWMutex” jest dostępny za darmo tutaj w sieci. Aby ćwiczyć ją interaktywnie (wbudowany edytor kodu i tutor AI dostępny 24/7) i odblokować resztę kursu Go Academy, przejdź na CoddyKit PRO. Kurs Go Academy zawiera 4 lekcji w sumie.
Co nauczysz się w „sync.Mutex i sync.RWMutex”?
Wzorce blokad oraz blokad odczytu i zapisu Ćwiczysz Go Academy z praktycznym kodem, który uruchamiasz bezpośrednio w przeglądarce, a tutor AI dostępny 24/7 odpowiada na Twoje pytania podczas pracy nad lekcją.
Czy potrzebuję doświadczenia, aby zacząć Go Academy?
Nie wymagamy żadnego doświadczenia. Go Academy w CoddyKit jest strukturyzowany dla początkujących i zaawansowanych użytkowników, więc możesz zacząć tutaj lub od początku i uczyć się w swoim tempie. To lekcja 1 z 4.
Ile czasu zajmuje lekcja „sync.Mutex i sync.RWMutex”?
Większość lekcji CoddyKit trwa około 5–10 minut. Każda lekcja to mały, interaktywny krok, dzięki czemu robisz systematyczne postępy i zawsze wracasz dokładnie do tego samego miejsca — na webie i w aplikacji.
Czy mogę pisać i uruchamiać kod w tej lekcji Go Academy?
Tak. Każda lekcja Go Academy zawiera wbudowany edytor kodu, więc piszesz i uruchamiasz prawdziwy kod bezpośrednio w przeglądarce i od razu otrzymujesz sprzężenie zwrotne od AI — bez konfiguracji na komputerze.
Wszystkie lekcje w tym kursie
- sync.Mutex i sync.RWMutex
- sync.WaitGroup
- sync.Once i sync.Map
- Detektor wyścigów i bezpieczne wzorce