锁/竞争(互斥锁、读写锁、原子锁)
a. import(“sync”)
b. 互斥锁, var mu sync.Mutex (只有一个释放之后,下一个才能进去)(sync.Mutex类型只有两个公开的指针方法:Lock、Unlock)
c. 读写锁, var mu sync.RWMutex(读不锁,只有写才锁)
d.原子锁,import "sync/atomic"
比如map,文件等被多个goroutine修改,则要做好锁。
只读无需加锁
用go build -race xxx.go来编译,并运行二进制文件来查看竞争关系
互斥锁举例:
a := make(map[int]int, 5) a[0] = 10 fmt.Println(a) for i := 0; i < 2; i++ { go func(b map[int]int){ //设置互斥锁 lock.Lock() a[0] = rand.Intn(100) lock.Unlock() }(a) } //互斥锁不读还是写,都要设置才能确保不竞争 lock.Lock() fmt.Println(a) lock.Unlock()
读写锁(包括原子锁)举例:
package mainimport ( "sync" "fmt" "math/rand" "time" "sync/atomic")var rwLock sync.RWMutexfunc main() { var count int32 //读写锁 a := make(map[int]int, 5) a[0] = 10 fmt.Println(a) for i := 0; i < 2; i++ { go func(b map[int]int){ //写的锁是Lock rwLock.Lock() a[0] = rand.Intn(100) rwLock.Unlock() }(a) } for i := 0; i < 100; i++ { go func(b map[int]int){ //读的锁是RLock rwLock.RLock() fmt.Println(a) //原子锁引用赋值count,每次加一 atomic.AddInt32(&count, 1) rwLock.RUnlock() }(a) } time.Sleep(time.Second) //输出原子锁次数也要有固定写法 fmt.Println(atomic.LoadInt32(&count))}
声明:本站所有文章资源内容,如无特殊说明或标注,均为采集网络资源。如若本站内容侵犯了原著者的合法权益,可联系本站删除。