/*
go互斥
上面的例子汇总 我们看过了如何在多个协程之间 原子地访问计数器
对于更复杂的例子
我们可以使用Mutex来在多个协程之间安全地访问数据
*/
package main
import (
"fmt"
"math/rand"
"runtime"
"sync"
"sync/atomic"
"time"
)
func main() {
var state = make(map[int]int)
//这个mutex将同步对状态的访问
var mutex = &sync.Mutex{}
var ops int64 = 0
for r := 0; r < 100; r++ {
go func() {
total := 0
for {
key := rand.Intn(5)
mutex.Lock()
total += state[key]
mutex.Unlock()
atomic.AddInt64(&ops, 1)
/*
为了保证这个协程不会让调度器处于饥饿状态
我们显示地使用runtime.Gosched 释放资源控制权
*/
runtime.Gosched()
}
}()
}
for w := 0; w < 10; w++ {
go func(){
for {
key := rand.Intn(5)
val := rand.Intn(100)
mutex.Lock()
state[key] = val
mutex.Unlock()
atomic.AddInt64(&ops, 1)
runtime.Gosched()
}
}
}
time.Sleep(time.Second)
opsFinal := atomic.LoadInt64(&ops)
fmt.Println(opsFinal)
mutex.Lock()
fmt.Println(state)
mutex.Unlock()
}