为什么 goroutine 中的无缓冲通道得到这个命令

why the unbuffered channel in the goroutine got this order

我正在用 goroutines 和 channels 写一些 golang 并发代码 这是我的代码:

package main

import "fmt"

func main() {
    in := make(chan int)

    go func() {
        fmt.Println("Adding num to channel")
        in <- 1
        fmt.Println("Done")
    }()
    val := <- in
    fmt.Println(val)
}

我做了一个无缓冲的通道,在我看来,里面的通道必须等到外面的通道读取它,输出可能是这样的:

Adding num to channel
1
Done

但实际上,输出是:

Adding num to channel
Done
1

我很困惑为什么内部无缓冲通道只是 运行 而没有等待读取

您对输出的解释不正确。 goroutine 确实写入了通道,此时主 goroutine 确实读取了,但是 "Done" 的 printf 在值的 printf 之前执行。

同步操作在 goroutine 之间建立 "happened before" 关系。当 goroutine 写入通道时,唯一保证在通道写入之前发生的事情是 goroutine 中的第一个 println。一旦通道写入和相应的读取完成,剩下的 goroutine 和 main goroutine 可以按任何顺序执行。

在你的例子中,goroutine 在主 goroutine 之前执行。