Go语言的坑: Happens Before 保证

Go语言的坑: Happens Before 保证

[toc]

创建 goroutine 发生先于 goroutine 执行,所以下面这段代码先读一个变量,然后在 goroutine 中写变量不会发生 data race 问题:

i := 0
    go func() {
            i++    
    }()

goroutine 退出没有任何 happen before保证,例如下面代码会有 data race :

i := 0
    go func() {
            i++
    }()    
fmt.Println(i)

channel 操作中 send 操作是 happens before receive 操作 :

var c = make(chan int, 10)
var a string

func f() {
  a = "hello, world"
  c <- 0
}

func main() {
  go f()
  <-c
  print(a)
}

上面执行顺序应该是:

variable change -> channel send -> channel receive -> variable read

上面能够保证一定输出 “hello, world”。

close channel 是 happens before receive 操作,所以下面这个例子中也不会有 data race 问题:

i := 0
    ch := make(chan struct{})
    go func() {
            <-ch
            fmt.Println(i)
    }()
    i++
    close(ch)

在无缓冲的 channel 中 receive 操作是 happens before send 操作的,例如:

var c = make(chan int)
var a string

func f() {
  a = "hello, world"
  <-c
}

func main() {
  go f()
  c <- 0
  print(a)
}

这里同样能保证输出 hello, world。

Licensed under CC BY-NC-SA 4.0
Built with Hugo
主题 StackJimmy 设计