在不使用goroutines(在其作用域内)和将其传递给goroutines时,通道缓冲区如何在golang中工作?

时间:2018-12-17 12:10:44

标签: go goroutine

我是Golang的绝对新手。我正在通过环游学习,然后以自己的理解实施想法。我在使用goroutines时遇到问题。我创建了一个无缓冲的频道,然后向该频道发送了一个字符串。

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

抛出错误

  

致命错误:所有goroutine都在睡觉-死锁!

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

但是当我将p <- "Hello goroutine重构为goroutine

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

func sendHello(p chan string) {
    p <- "Hello goroutine"
}

它正常工作。我读到,在大多数情况下,我们不需要在映射,切片和通道中使用指针来修改值。 channel p是通过具有单独缓冲区的副本传递给func sendHello(p chan string) 的。我仍然无法摆脱困境。

1 个答案:

答案 0 :(得分:6)

请记住,通道有两个端点,一个是发件人和一个接收者。您的问题与执行顺序有关。

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

但是在第二个示例中,接收器绑定到通道,并且在之后执行常规程序,并且 sender receiver 都不会保持等待状态