Go race condition以及解决方法

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lzx_victory/article/details/83655861

形成条件

一般情况下是由于在没有加锁的情况下多个协程进行操作对同一个变量操作形成竞争条件.

如果没有锁的情况会输出结果非1001.


func main()  {
	c := 1
	g := sync.WaitGroup{}
	times := 1000
	for i:=0 ; i< times; i++ {
		g.Add(1)
		go func() {
			c++
			g.Done()
		}()
	}
	g.Wait()
	fmt.Println(c)
}

原因

多核CPU操作同一变量,可能会取到’旧’的值,是一个并发导致的错误.

检查方式

对项目执行竞争检测:

$ go test -race mypkg    // test the package
$ go run -race mysrc.go  // compile and run the program
$ go build -race mycmd   // build the command
$ go install -race mypkg // install the package

可以轻松的看到问题代码:

$ go run -race mtest.go

==================
WARNING: DATA RACE
Read at 0x00c0420080e0 by goroutine 7:
  main.main.func1()
      C:/Users/liuzexin/go/src/gotest/mtest.go:65 +0x42

Previous write at 0x00c0420080e0 by goroutine 6:
  main.main.func1()
      C:/Users/liuzexin/go/src/gotest/mtest.go:65 +0x5b

Goroutine 7 (running) created at:
  main.main()
      C:/Users/liuzexin/go/src/gotest/mtest.go:63 +0xec

Goroutine 6 (finished) created at:
  main.main()
      C:/Users/liuzexin/go/src/gotest/mtest.go:63 +0xec
==================
989
Found 1 data race(s)
exit status 66

解决方式

方式1:使用互斥锁sync.Mutex
方式2:使用管道

使用管道的效率要比互斥锁高,也符合Go语言的设计思想.

猜你喜欢

转载自blog.csdn.net/lzx_victory/article/details/83655861
今日推荐