The primary mechanism for managing state in Go is
communication over channels. We saw this for example
with worker pools. There are a few other
options for managing state though. Here we’ll
look at using the |
|
![]() ![]() package main
|
|
import (
"fmt"
"sync"
"sync/atomic"
)
|
|
func main() {
|
|
We’ll use an unsigned integer to represent our (always-positive) counter. |
var ops uint64
|
A WaitGroup will help us wait for all goroutines to finish their work. |
var wg sync.WaitGroup
|
We’ll start 50 goroutines that each increment the counter exactly 1000 times. |
for i := 0; i < 50; i++ {
wg.Add(1)
|
To atomically increment the counter we
use |
go func() {
for c := 0; c < 1000; c++ {
|
atomic.AddUint64(&ops, 1)
}
wg.Done()
}()
}
|
|
Wait until all the goroutines are done. |
wg.Wait()
|
It’s safe to access |
fmt.Println("ops:", ops)
}
|
We expect to get exactly 50,000 operations. Had we
used the non-atomic |
$ go run atomic-counters.go
ops: 50000
|
Next we’ll look at mutexes, another tool for managing state. |
Next example: Mutexes.