如果没有goroutine(在他们的范围内)使用它们传递给goroutines时,通道缓冲区如何在golang中工作?

top*_*ion 1 go goroutine

我是Golang的绝对新手.我正在通过Tour of Go学习,然后用我自己的理解实现想法.我遇到了goroutines的问题.我创建了一个无缓冲的通道,然后将一个字符串发送到该通道.

func main() {
    p := make(chan string)
    p <- "Hello goroutine"
    fmt.Println(<-p)
}
Run Code Online (Sandbox Code Playgroud)

抛出错误

致命错误:所有goroutines都睡着了 - 僵局!

我明白了,频道没有缓冲.(这就是原因.对吧?).

但是当我重构p <- "Hello goroutine一个goroutine时

func main() {
    p := make(chan string)
    go sendHello(p)
    fmt.Println(<-p)
}

func sendHello(p chan string) {
    p <- "Hello goroutine"
}
Run Code Online (Sandbox Code Playgroud)

它没有问题.我读到我们不需要在大多数情况下使用带有地图,切片和通道的指针来修改值.channel p传递到func sendHello(p chan string)通过副本里面有一个单独的缓冲区.我仍然无法理解它.

Ali*_*rus 7

请记住,频道有两端,发送者接收者.你的问题是关于执行的顺序.

在第一个示例中,当您使用无缓冲通道时,通道需要一个接收器,而在发送Hello goroutine消息时没有,并等待直到有一个(缓冲通道不是这种情况,因为它不需要等待) ,执行永远不会到达下一行(即死锁).

但是在第二个例子中,接收器绑定到通道并且之后执行了灌浆,并且发送器接收器都不会保持等待状态.