【发布时间】:2019-05-17 19:20:11
【问题描述】:
我是 Golang 的绝对新手。我正在通过 Tour of Go 学习,然后用我自己的理解来实施想法。我遇到了 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)。我仍然无法理解它。
【问题讨论】:
-
我不太明白你的问题。您的第二个示例使用 goroutine,这就是它不阻塞的原因。所以我不确定你为什么要猜测频道的副本(这完全不是发生的事情)。
-
这与指针或传递副本无关。发生了什么:你跨越了一个新的 goroutine,当这个 goroutine 在 sendHello 上工作时,主 goroutine 继续并等待,直到在 p 上发送了一些东西并从 p 中读取它。发送发生在第二个 goroutine 中。
-
在您的第一个代码中,您的程序一旦到达
p <- "Hello"就无法前进,因为没有其他 goroutine 可供读取。在您的第二个示例中,您确实有两个 groroutines,而一个正在尝试发送,另一个正在尝试读取并且值将通过通道。再说一遍:这与值如何传递给函数、“引用”或指针无关。 -
@Volker println 通过
-
对不起,我已经修复了评论。