golang mutex example

Пользователь

от anastacio.hane , в категории: Общие вопросы , 4 года назад

Хочу узнать, как в Golang’е избежать конфликтов, когда мне нужно, чтобы только одна go-процедура имела доступ к переменной в любой момент времени?


Facebook Vk Ok Twitter LinkedIn Telegram Whatsapp Pocket

6 ответов

Пользователь

от bailee , 4 года назад

Советую зайти на русскоязычный сайт gobyexample.ru , там есть серия статей – Go в примерах. И как раз есть про мьютексы. В этой статье найдёшь реальный код и объяснение чуть ли не каждой строчки. Думаю, поймёшь.


Пользователь

от tessie_jacobs , 4 года назад

Эта концепция известна как взаимное исключение, и общепринятым названием для структуры данных, которая это позволяет, является мьютекс (mutex).

Стандартная библиотека Go предоставляет взаимное исключение с помощью sync.Mutex и двух его методов:

Lock

Unlock


Пользователь

от tessie_jacobs , 4 года назад

Также ты можешь объявить блок кода, который будет выполняться при взаимном исключении, окружив его вызовами к Lock и Unlock, как показано в методе Inc.

Мы также можем использовать defer, чтобы удостовериться, что мьютекс будет освобожден, как в методе Value.


Пользователь

от bradly.ledner , 4 года назад

Держи пример реального кода, в котором используются мьютексы:

 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"))
}

Пользователь

от newell , 4 года назад

Зайди на сайт metanit.com, там пару лет назад вышла статья про Мьютексы. В статье несколько примеров и необходимая для новичка теория. Должно помочь тебе.


Пользователь

от anastacio.hane , 4 года назад

Спасибо большое, ребят, что бы я без вас делал? Пойду пробовать теперь избегать конфликты между разными процедурами. А то постоянно ошибки из-за этого возникали.