Все вопросы

36 Конкурентность

Когда нужен Mutex?

sync.Mutex нужен, когда несколько горутин меняют одни и те же данные. Lock берёт исключительный доступ, Unlock отпускает. Между ними — критическая секция. Без замка одновременный n++ — это гонка, и результат меньше числа итераций.

defer mu.Unlock() страхует от раннего return. Мьютекс нельзя копировать: замок должен быть один на данные. Обычно его кладут рядом с данными в структуру и передают эту структуру по указателю.

RWMutex пускает много читателей или одного писателя. Он окупается, когда чтений заметно больше записей. Для короткого счётчика хватает обычного Mutex.

Пример

Go

сто увеличений под одним замком

package main

import (
    "fmt"
    "sync"
)

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