go 竞态检测

2022-03-19  本文已影响0人  wayyyy

Go 工具套件在 Go 版本 1.1 引入了一个竞态检测工具(race detector)。这个竞态检测工具是在编译流程中内置到你程序的代码。一旦你的程序开始运行,它能够发现和报告任何他所检测到的竞态情况

package main

import (
    "fmt"
    "sync"
    "time"
)

var Wait sync.WaitGroup
var Counter int = 0

func main() {
    for routine := 1; routine <= 2; routine++ {
        Wait.Add(1)
        go Work(routine)
    }

    Wait.Wait()
    fmt.Printf("Final Counter: %d\n", Counter)
}

func Work(id int) {
    for i := 0; i < 10; i++ {
        Counter++
        time.Sleep(1 * time.Nanosecond)
    }

    Wait.Done()
}

使用go build -race -o main.out main.go(也可以直接使用go run -race),然后运行:

[root@admin go-race]# go build -race -o main.out main.go
[root@admin go-race]# ls
[root@admin go-race]# ./main.out 
==================
WARNING: DATA RACE
Read at 0x000000609908 by goroutine 8:
  main.Work()
      /root/code/go_work/project/gotour/go-race/main.go:24 +0x47

Previous write at 0x000000609908 by goroutine 7:
  main.Work()
      /root/code/go_work/project/gotour/go-race/main.go:24 +0x64

Goroutine 8 (running) created at:
  main.main()
      /root/code/go_work/project/gotour/go-race/main.go:15 +0x75

Goroutine 7 (running) created at:
  main.main()
      /root/code/go_work/project/gotour/go-race/main.go:15 +0x75
==================
Final Counter: 20
Found 1 data race(s)

加锁,修改之:

package main

import (
    "fmt"
    "sync"
    "time"
)

var Wait sync.WaitGroup
var Counter int = 0
var CounterLock sync.Mutex

func main() {
    for routine := 1; routine <= 2; routine++ {
        Wait.Add(1)
        go Work(routine)
    }

    Wait.Wait()
    fmt.Printf("Final Counter: %d\n", Counter)
}

func Work(id int) {
    for i := 0; i < 10; i++ {
        CounterLock.Lock()
        Counter++
        CounterLock.Unlock()
        time.Sleep(1 * time.Nanosecond)
    }

    Wait.Done()
}

再次运行,检测通过。

go 语言常见并发问题
上一篇 下一篇

猜你喜欢

热点阅读