Следите за новинками
в нашем Telegram канале. Жми, чтобы подписаться:)
⊗goSpSyMx 168 of 280 menu
◀ ▶

Взаимное исключение в Go

Замок взаимного исключения пускает к общему счетчику только одну горутину. Остальные ждут, пока владелец не отпустит доступ; тогда следующая ветка сможет войти и безопасно изменить число.

Тип sync.Mutex хранят рядом с защищаемым полем. Перед изменением общей переменной вызывают Lock, после работы Unlock. Отпуск замка удобно ставить в отложенной функции, чтобы он сработал и при раннем выходе из ветки.

Сто веток без замка могут потерять часть приращений:

package main import ( "fmt" "sync" ) func main() { var n int var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() n++ }() } wg.Wait() fmt.Println(n) }

На экране часто число меньше ста: две ветки читают одно и то же старое значение и обе пишут увеличенное на единицу.

Тот же цикл с замком дает ровно сто:

package main import ( "fmt" "sync" ) func main() { var n int var mu sync.Mutex var wg sync.WaitGroup wg.Add(100) for i := 0; i < 100; i++ { go func() { defer wg.Done() mu.Lock() defer mu.Unlock() n++ }() } wg.Wait() fmt.Println(n) }

Дан следующий код:

var total int var wg sync.WaitGroup func add(wg *sync.WaitGroup) { defer wg.Done() total++ }

Добавьте поле замка, оберните приращение захватом и отпуском и запустите десять веток с ожиданием группы. Выведите total.

Дан следующий код:

var mu sync.Mutex var x int func inc() { mu.Lock() x++ }

Скажите, чем опасен такой inc при вызове из нескольких горутин.

Скажите, зачем Unlock в примере со стом ветками ставят в отложенной функции сразу после Lock.

← →
↑
Мы используем cookie для работы сайта, аналитики и персонализации. Обработка данных происходит согласно Политике конфиденциальности.
принять все настроить отклонить