РЕПЕТИТОР математика физика информатика
Для школьников и студентов. Подтягивание пробелов. ЦЭ, ЦТ, ОГЭ, ЕГЭ.
Идет набор на ЛЕТО. Жмите для подробностей:)
832 of 1593 menu

Тип sync.Mutex

Тип sync.Mutex предоставляет механизм взаимного исключения для защиты критических секций в многопоточных программах на Go. Он позволяет синхронизировать доступ к общим ресурсам, гарантируя, что только одна горутина одновременно может выполнять защищенный участок кода. Основные методы мьютекса — это Lock, который блокирует мьютекс, и Unlock, который освобождает блокировку. Мьютекс должен создаваться с помощью ключевого слова var или через new, и его нулевое значение готово к использованию.

Синтаксис

var mu sync.Mutex mu.Lock() // критическая секция mu.Unlock()

Пример

Давайте рассмотрим базовый пример использования мьютекса для защиты счетчика от состояния гонки:

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

Результат выполнения кода:

100

Пример

Покажем, что происходит, если не использовать мьютекс. В этом случае счетчик может стать меньше ожидаемого значения из-за состояния гонки:

package main import ( "fmt" "sync" ) func main() { counter := 0 var wg sync.WaitGroup for i := 0; i < 100; i++ { wg.Add(1) go func() { defer wg.Done() counter++ // гонка данных }() } wg.Wait() fmt.Println(counter) }

Результат выполнения кода (может быть разным):

95

Пример

Мьютекс также можно использовать для защиты структуры данных. В этом примере мы защищаем доступ к карте:

package main import ( "fmt" "sync" ) type SafeMap struct { mu sync.Mutex m map[string]int } func NewSafeMap() *SafeMap { return &SafeMap{ m: make(map[string]int), } } func (sm *SafeMap) Set(key string, value int) { sm.mu.Lock() defer sm.mu.Unlock() sm.m[key] = value } func (sm *SafeMap) Get(key string) int { sm.mu.Lock() defer sm.mu.Unlock() return sm.m[key] } func main() { safeMap := NewSafeMap() var wg sync.WaitGroup for i := 0; i < 10; i++ { wg.Add(1) go func(i int) { defer wg.Done() key := fmt.Sprintf("key%d", i) safeMap.Set(key, i) }(i) } wg.Wait() fmt.Println(safeMap.Get("key5")) }

Результат выполнения кода:

5

Смотрите также

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