Являются ли операции с Mutex блокирующими
1️⃣ Как кратко ответить
Да, операции с Mutex в Go являются блокирующими. Когда горутина пытается захватить заблокированный Mutex, она будет заблокирована до тех пор, пока Mutex не будет освобожден другой горутиной.
2️⃣ Подробное объяснение темы
Mutex (сокращение от "mutual exclusion" — взаимное исключение) — это примитив синхронизации, который используется для предотвращения одновременного доступа к общим ресурсам несколькими горутинами. В языке Go Mutex предоставляется пакетом sync.
Когда одна горутина захватывает Mutex, другие горутины, которые пытаются захватить тот же Mutex, будут заблокированы до тех пор, пока первый Mutex не будет освобожден. Это означает, что операции с Mutex являются блокирующими.
Пример использования Mutex
Рассмотрим пример, где несколько горутин пытаются увеличить общий счетчик:
package main
import (
"fmt"
"sync"
)
func main() {
var mu sync.Mutex
counter := 0
var wg sync.WaitGroup
// Запускаем 10 горутин
for i := 0; i < 10; i++ {
wg.Add(1)
go func() {
defer wg.Done()
// Захватываем Mutex перед изменением общего ресурса
mu.Lock()
// Увеличиваем общий счетчик
counter++
// Освобождаем Mutex после изменения
mu.Unlock()
}()
}
// Ожидаем завершения всех горутин
wg.Wait()
fmt.Println("Final Counter:", counter)
}
Объяснение кода:
-
var mu sync.Mutex: Создаем переменнуюmuтипаsync.Mutex. Это наш Mutex, который будет использоваться для синхронизации доступа к переменнойcounter. -
counter := 0: Инициализируем общий счетчик, который будет увеличиваться горутинами. -
var wg sync.WaitGroup: СоздаемWaitGroup, чтобы дождаться завершения всех горутин. -
for i := 0; i < 10; i++: Запускаем цикл для создания 10 горутин. -
wg.Add(1): Увеличиваем счетчикWaitGroupна 1 перед запуском каждой горутины, чтобыWaitGroupзнал, сколько горутин нужно ожидать. -
go func() { ... }(): Анонимная функция, которая запускается как горутина. -
defer wg.Done(): Уменьшаем счетчикWaitGroupна 1, когда горутина завершает выполнение. -
mu.Lock(): Захватываем Mutex. Если Mutex уже захвачен другой горутиной, текущая горутина будет заблокирована до тех пор, пока Mutex не будет освобожден. -
counter++: Увеличиваем общий счетчик. Это критическая секция, доступ к которой должен быть синхронизирован. -
mu.Unlock(): Освобождаем Mutex, позволяя другим горутинам захватить его и выполнить свою критическую секцию. -
wg.Wait(): Ожидаем завершения всех горутин, чтобы убедиться, что все изменения счетчика завершены до вывода результата.
Mutex используется для обеспечения того, что только одна горутина может изменять общий ресурс в любой момент времени, предотвращая таким образом состояние гонки. Блокирующее поведение Mutex гарантирует, что горутины будут ждать своей очереди для доступа к ресурсу, что делает операции с Mutex блокирующими.
🔒 Подпишись на бусти автора и стань Алигатором, чтобы получить полный доступ к функционалу сайта и отслеживать свой прогресс!
Подписаться