代码如下:
package main
import (
"sync"
"sync/atomic"
)
func main() {
var n int32
var m sync.RWMutex
go func() {
for {
atomic.LoadInt32(&n)
}
}()
go func() {
for {
m.RLock()
atomic.AddInt32(&n, 1)
m.RUnlock()
}
}()
go func() {
for {
m.Lock()
n = 0
m.Unlock()
}
}()
go func() {
for {
m.Lock()
n -= 1
m.Unlock()
}
}()
// do something to keep goroutines running here
......
}
playground link: https://play.golang.org/p/Mrdetw46mXR
race 内容:
$ go run -race main.go
==================
WARNING: DATA RACE
Write at 0x00c000096000 by goroutine 7:
main.main.func3()
/Users/purewhite/go/src/xxx/main.go:26 +0x46
Previous read at 0x00c000096000 by goroutine 5:
sync/atomic.LoadInt32()
/usr/local/Cellar/go/1.12.6/libexec/src/runtime/race_amd64.s:206 +0xb
main.main.func1()
/Users/purewhite/go/src/xxx/main.go:13 +0x38
Goroutine 7 (running) created at:
main.main()
/Users/purewhite/go/src/xxx/main.go:23 +0x115
Goroutine 5 (running) created at:
main.main()
/Users/purewhite/go/src/xxx/main.go:11 +0xbd
==================
Found 1 data race(s)
exit status 66
1
fork 2019-07-05 19:41:17 +08:00
把 mutex 去了,
用 atomic.StoreInt32(&n, 0) 代替 n = 0 用 atomic.AddInt32(&n, -1) 代替 n -= 1 |
2
100knights 2019-07-05 22:02:23 +08:00
为啥你修改要用读锁?
|
3
liulaomo 2019-07-05 22:33:59 +08:00
这写法看着真别扭。很明显第一个协程和第三第四个有竞争。
按照你这种写法,你可以把第一个和第二个一样加个读锁。 |
4
whoami9894 2019-07-05 23:06:58 +08:00 via Android
为什么原子操作还加锁
|
5
reus 2019-07-06 00:19:17 +08:00
要么全部用锁,要么全部用原子操作,混用就是 race 啊
|