【问题标题】:Why does select in golang only works with channels in goroutine?为什么 golang 中的 select 只适用于 goroutine 中的通道?
【发布时间】:2016-09-06 08:08:06
【问题描述】:

考虑以下go playground

    package main

    import "fmt"

    func main() {
        messages := make(chan string)

        messages <- "my msg"

        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        }

    }

上面的代码会报错

fatal error: all goroutines are asleep - deadlock!

然而

如果我把它改成

    package main

    import "fmt"

    func main() {
        messages := make(chan string)

        go func() {
            messages <- "my msg"
        }()
        select {
        case msg := <-messages:
            fmt.Println("received message", msg)
        }

    }

它会起作用的。

这种行为有什么特殊原因吗?

代码不应该在第一种情况下按顺序执行,以便在到达 select 语句时,将传递 msg 并捕获 case msg := &lt;-messages 吗?

【问题讨论】:

    标签: go channel


    【解决方案1】:

    代码不应该在第一种情况下以顺序方式执行,以便在到达 select 语句时,将传递 msg 并捕获 case msg :=

    永远不会到达 select 语句,这就是您的第一个代码中的问题。

    声明

    messages <- "my msg"
    

    想要将字符串推送到频道中,但是由于您创建了一个无缓冲的频道

    messages := make(chan string)
    

    goroutine 一直在等待有人真正从通道中读取,因此它可以将字符串推送到通道。您可以将某些内容推送到无缓冲的通道如果某个地方有一个 goroutine 从它读取!

    尝试使用缓冲通道的第一个示例:

    messages := make(chan string, 1)
    

    它应该可以按您的预期工作。

    【讨论】:

      猜你喜欢
      • 2020-08-16
      • 2015-12-08
      • 2017-02-14
      • 1970-01-01
      • 1970-01-01
      • 2018-10-02
      • 2020-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多