Golang slice append 使用Synv.Mutex后仍然存在Data Race,如何可以消除Data Race?
1. 运行环境
go version go1.17.9 linux/amd64
Ubuntu 20.04
2. 问题描述?
在复现一个分布式算法时,出现Data Race的提示,存在某些消息没有被追加到slice中。然后在本地写了一个简单的程序,使用go run -race .
运行后发现的确是存在Data Race。
由于是初学Goalng,对于Go语言的机制不太熟悉,我觉得大概率是因为Data Race的原因导致某些数据没有append到slice中,尽管已经使用了 Sync.mutex 加锁,不知道有没有可以解决的办法?谢谢!
这是本地模拟用的代码:
type log struct {
mu sync.Mutex
sl []int64
}
func (l *log) add(i int64) {
l.mu.Lock()
defer l.mu.Unlock()
fmt.Printf("data: %d --- slice: %v \n", i, l.sl)
l.sl = append(l.sl, i)
}
func main() {
l := &log{
sl: make([]int64, 0),
}
for i := 0; i < 10; i++ {
t := i
go l.add(int64(t))
}
fmt.Println(len(l.sl))
fmt.Println(l.sl)
}
这是使用go run -race .
的运行结果:
==================
WARNING: DATA RACE
Read at 0x00c000134008 by main goroutine:
main.main()
/home/user/go/src/abcd/main.go:28 +0x185
Previous write at 0x00c000134008 by goroutine 14:
main.(*log).add()
/home/user/go/src/abcd/main.go:17 +0x211
main.main·dwrap·2()
/home/user/go/src/abcd/main.go:26 +0x47
Goroutine 14 (finished) created at:
main.main()
/home/user/go/src/abcd/main.go:26 +0xcf
==================
10
==================
WARNING: DATA RACE
Read at 0x00c0000a4048 by main goroutine:
reflect.typedmemmove()
/usr/local/go/src/runtime/mbarrier.go:178 +0x0
reflect.packEface()
/usr/local/go/src/reflect/value.go:123 +0xae
reflect.valueInterface()
/usr/local/go/src/reflect/value.go:1394 +0x18a
reflect.Value.Interface()
/usr/local/go/src/reflect/value.go:1364 +0xc9
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:722 +0xca
fmt.(*pp).printValue()
/usr/local/go/src/fmt/print.go:865 +0x22d8
fmt.(*pp).printArg()
/usr/local/go/src/fmt/print.go:712 +0xdf4
fmt.(*pp).doPrintln()
/usr/local/go/src/fmt/print.go:1169 +0x225
fmt.Fprintln()
/usr/local/go/src/fmt/print.go:264 +0x5d
fmt.Println()
/usr/local/go/src/fmt/print.go:274 +0x23d
main.main()
/home/user/go/src/abcd/main.go:29 +0x1d7
Previous write at 0x00c0000a4048 by goroutine 16:
main.(*log).add()
/home/user/go/src/abcd/main.go:17 +0x1eb
main.main·dwrap·2()
/home/user/go/src/abcd/main.go:26 +0x47
Goroutine 16 (finished) created at:
main.main()
/home/user/go/src/abcd/main.go:26 +0xcf
==================
[0 1 2 4 3 5 6 7 8 9]
Found 2 data race(s)
exit status 66
这两句没加锁导致的