statefule goroutines _ golang
In the previous example we used explicit locking with mutexes to synchronize access to shared state across multiple goroutines. Another option is to use the built-in synchronization features of goroutines and channels to achieve the same result. This channel-based approach aligns with Go's ideas of sharing memory by communivating and having each piece of data owned by exactly 1 goroutine
package main import ( "fmt" "math/rand" "sync/atomic" "time" ) type read0p struct { key int resp chan int } type write0p struct { key int val int resp chan bool } func main() { var ops int64 = 0 reads := make(chan *read0p) writes := make(chan *write0p) go func() { var state = make(map[int]int) for { select { case read := <-reads: read.resp <- state[read.key] case write := <-writes: state[write.key] = write.val write.resp <- true } } }() for r := 0; r < 100; r++ { go func() { for { read := &read0p{ key: rand.Intn(5), resp: make(chan int), } reads <- read fmt.Println("<-read.resp:", <-read.resp) atomic.AddInt64(&ops, 1) } }() } for w := 0; w < 10; w++ { go func() { for { write := &write0p{ key: rand.Intn(5), val: rand.Intn(100), resp: make(chan bool), } writes <- write <-write.resp atomic.AddInt64(&ops, 1) } }() } time.Sleep(time.Second) opsFinal := atomic.LoadInt64(&ops) fmt.Println("ops:", opsFinal) }
ops: 329696
总结 :
1 : atomic.AddInt64 原子性的增加一个值