Урок объясняет механизмы синхронизации в Go: работу мьютексов для защиты общих данных, роль defer в безопасной разблокировке, а также использование wait groups для ожидания завершения множества горутин.
Конкурентные программы могут одновременно обращаться к одним и тем же данным. Без синхронизации это приводит к гонкам данных и непредсказуемому поведению.
Go предоставляет два ключевых инструмента синхронизации: - Mutex - защита общих данных
Mutex гарантирует, что в критическую секцию попадёт только одна горутина.
Lock() - блокирует доступUnlock() - разблокируетtype SyncedData struct {
inner map[string]int
mutex sync.Mutex
}
func (d *SyncedData) Insert(k string, v int) {
d.mutex.Lock()
defer d.mutex.Unlock()
d.inner[k] = v
}
func (d *SyncedData) Get(k string) int {
d.mutex.Lock()
defer d.mutex.Unlock()
return d.inner[k]
}
defer гарантирует разблокировку даже при ошибках.
Без defer:
d.mutex.Lock()
if somethingBad {
return // забыли Unlock → deadlock
}
d.mutex.Unlock()
С defer:
d.mutex.Lock()
defer d.mutex.Unlock()
Никаких утечек блокировок.
WaitGroup позволяет дождаться завершения всех конкурентных задач.
Add(n) - сколько горутин будет запущеноDone() - горутина завершенаWait() - блокирует выполнение до завершения всех задачvar wg sync.WaitGroup
sum := 0
for i := 0; i < 20; i++ {
wg.Add(1)
value := i
go func() {
defer wg.Done()
sum += value
}()
}
wg.Wait()
fmt.Println("sum =", sum)