Советую зайти на русскоязычный сайт gobyexample.ru , там есть серия статей – Go в примерах. И как раз есть про мьютексы. В этой статье найдёшь реальный код и объяснение чуть ли не каждой строчки. Думаю, поймёшь.
Эта концепция известна как взаимное исключение, и общепринятым названием для структуры данных, которая это позволяет, является мьютекс (mutex).
Стандартная библиотека Go предоставляет взаимное исключение с помощью sync.Mutex и двух его методов:
Lock
Unlock
Также ты можешь объявить блок кода, который будет выполняться при взаимном исключении, окружив его вызовами к Lock и Unlock, как показано в методе Inc.
Мы также можем использовать defer, чтобы удостовериться, что мьютекс будет освобожден, как в методе Value.
Держи пример реального кода, в котором используются мьютексы:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
package main import ( "fmt" "sync" "time" ) // SafeCounter безопасен для конкурентного использования. type SafeCounter struct { v map[string]int mux sync.Mutex } // Inc инкрементирует счетчик для переданного ключа. func (c *SafeCounter) Inc(key string) { c.mux.Lock() // Вызван Lock, поэтому только одна go-процедура за раз // может получить доступ к карте c.v c.v[key]++ c.mux.Unlock() } // Value возвращает текущее значение счетчика // для переданного ключа. func (c *SafeCounter) Value(key string) int { c.mux.Lock() // Вызван Lock, поэтому только одна go-процедура за раз // может получить доступ к карте c.v defer c.mux.Unlock() return c.v[key] } func main() { c := SafeCounter{v: make(map[string]int)} for i := 0; i < 1000; i++ { go c.Inc("somekey") } time.Sleep(time.Second) fmt.Println(c.Value("somekey")) } |
Зайди на сайт metanit.com, там пару лет назад вышла статья про Мьютексы. В статье несколько примеров и необходимая для новичка теория. Должно помочь тебе.
Спасибо большое, ребят, что бы я без вас делал? Пойду пробовать теперь избегать конфликты между разными процедурами. А то постоянно ошибки из-за этого возникали.