go_playground/5-go-by-example/39-mutexes.go

50 lines
940 B
Go

package main
import (
"fmt"
"sync"
)
// holds a map of counters
// add a Mutex to synchronize access
type Container struct {
mu sync.Mutex
counters map[string]int
}
func (c *Container) inc(name string) {
// lock the mutex before accessing counters
c.mu.Lock()
// unlock it at the end of the function using defer
defer c.mu.Unlock()
c.counters[name]++
}
// mutex to safely access data across multiple goroutines
func main() {
c := Container{
// the zero value of a mutex is usable as-is
counters: map[string]int{"a": 0, "b": 0},
}
var wg sync.WaitGroup
// increments a named counter in a loop
doIncrement := func(name string, n int) {
for i := 0; i < n; i++ {
c.inc(name)
}
wg.Done()
}
// run several goroutines concurrently
wg.Add(3)
go doIncrement("a", 10000)
go doIncrement("a", 10000)
go doIncrement("b", 10000)
// wait a for the goroutines to finish
wg.Wait()
fmt.Println(c.counters)
}