当两个或更多goroutine尝试访问同一资源时, Go中就会出现竞争条件。当变量在不考虑其他例程的情况下尝试读取和写入资源时, 可能会发生这种情况。
Go race条件示例
package main
import (
"sync"
"time"
"math/rand"
"fmt"
)
var wait sync.WaitGroup
var count int
funcincrement(s string){
for i :=0;
i<
10;
i++ {
x := count
x++;
time.Sleep(time.Duration(rand.Intn(4))*time.Millisecond)
count = x;
fmt.Println(s, i, "Count: ", count)}
wait.Done()}
func main(){
wait.Add(2)
go increment("foo: ")
go increment("bar: ")
wait.Wait()
fmt.Println("last count value " , count)
}
输出:
foo:0 Count:1
bar:0 Count:1
foo:1 Count:2
foo:2 Count:3
foo:3 Count:4
bar:1 Count:2
foo:4 Count:5
foo:5 Count:6
foo:6 Count:7
bar:2 Count:3
bar:3 Count:4
bar:4 Count:5
foo:7 Count:8
foo:8 Count:9
bar:5 Count:6
bar:6 Count:7
foo:9 Count:10
bar:7 Count:8
bar:8 Count:9
bar:9 Count:10
last count value10
【Go race使用】如你在上面的示例中看到的, 计数资源由2个go例程访问。每个例程迭代10次。在这种情况下, count变量最后应为20。并非如此, 因为它是在模拟race条件。