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.