package main
import (
"fmt"
"math/rand"
"time"
)
type Test struct {
Data *Test2
}
type Test2 struct {
Id int
}
func main() {
rand.Seed(time.Now().Unix())
o := Test{
Data: &Test2{Id: 100},
}
go func() {
for {
time.Sleep(time.Second)
o.Data = &Test2{Id: rand.Intn(10000)}
}
}()
for {
time.Sleep(time.Second)
if o.Data != nil {
fmt.Println(o.Data.Id)
}
}
}
//以上代码并发安全吗,求解释
```golang
go run --race race_wcd.go
100
==================
WARNING: DATA RACE
Write at 0x00c00012a018 by goroutine 7:
main.main.func1()
/Users/wcd/code/go/src/tools/race_wcd.go:23 +0xac
Previous read at 0x00c00012a018 by main goroutine:
main.main()
/Users/wcd/code/go/src/tools/race_wcd.go:29 +0x179
Goroutine 7 (running) created at:
main.main()
/Users/wcd/code/go/src/tools/race_wcd.go:20 +0x15e
==================
==================
WARNING: DATA RACE
Read at 0x00c00012e010 by main goroutine:
main.main()
/Users/wcd/code/go/src/tools/race_wcd.go:30 +0x1a5
Previous write at 0x00c00012e010 by goroutine 7:
main.main.func1()
/Users/wcd/code/go/src/tools/race_wcd.go:23 +0x91
Goroutine 7 (running) created at:
main.main()
/Users/wcd/code/go/src/tools/race_wcd.go:20 +0x15e
==================
7266
6979
```
#2
更多评论
* 非并发安全,在并发读写时,会存在读到没有写完的对象,Golang 不保证任何单独的操作是原子性的,除非使用 atomic 包里提供的原语或加锁。
* 也可以看下这篇文章: https://studygolang.com/articles/29922
* go run -race main.go , 开启竞态检测,会有WARNING提示
#1