【问题标题】:How channel buffers work in golang when used without goroutines (within their scope) vs when they are passed to goroutines?在没有 goroutines 的情况下(在其范围内)与将它们传递给 goroutines 时,通道缓冲区如何在 golang 中工作?
【发布时间】: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 &lt;- "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 &lt;- "Hello" 就无法前进,因为没有其他 goroutine 可供读取。在您的第二个示例中,您确实有两个 groroutines,而一个正在尝试发送,另一个正在尝试读取并且值将通过通道。再说一遍:这与值如何传递给函数、“引用”或指针无关
  • @Volker println 通过
  • 对不起,我已经修复了评论。

标签: go goroutine


【解决方案1】:

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

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

但是在第二个例子中,receiver被绑定到channel,groutine在之后执行,并且senderreceiver都不会保持等待状态.

【讨论】:

  • 这很简短,正是我想知道的。谢谢。也有我的支持。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-22
  • 1970-01-01
相关资源
最近更新 更多