Camada Zero · 08 · Mutex vs Channels

Estado compartilhado entre goroutines quebra calado. Roda no modo sem proteção e olha o contador parar num número errado por causa da corrida. Depois liga o mutex e o channel: os dois consertam, cada um do seu jeito, e você vê o que isso custa em contenção.
0 / esperado 0
0Contenção máx (esperando)
Updates perdidos
Escolhe o modo e clica em Rodar. Cada goroutine faz 4 incrementos; o esperado é goroutines × 4.
na seção crítica esperando o lock corrida (lendo junto) terminou
Incrementar um contador é read-modify-write: lê, soma 1, grava. Se duas goroutines leem o mesmo valor antes de qualquer uma gravar, uma escrita sobrescreve a outra e um incremento some. O resultado fica menor que o esperado, de forma não-determinística. A regra: mutex pra proteger estado, channel pra comunicar.
FerramentaUse para
sync.Mutexproteger estado / seção crítica (contador, map, cache)
sync.RWMutexmuitos leitores, poucos escritores
channeltransferir posse, coordenar, pipelines
sync/atomiccontador simples sem lock (mais rápido)

Mutex: proteger o estado

type Counter struct {
    mu sync.Mutex
    n  int
}
func (c *Counter) Inc() {
    c.mu.Lock()
    c.n++ // seção crítica: curta
    c.mu.Unlock()
}

RWMutex: muitos leitores

mu.RLock() // leituras em paralelo
_ = cache[key]
mu.RUnlock()

mu.Lock() // escritor exclusivo
cache[key] = val
mu.Unlock()

Channel: uma goroutine dona

ch := make(chan int)
go func() { // só ela toca em n
    n := 0
    for d := range ch {
        n += d
    }
}()
ch <- 1 // cada goroutine só envia

🧠 Desafio — Mutex vs Channels

Roda os três modos aqui de cima antes de responder. As duas últimas são de reflexão: escreve a sua e só então revela o modelo.