简体   繁体   English

为什么golang中的select仅适用于goroutine中的通道?

[英]Why does select in golang only works with channels in goroutine?

Consider the following go playground 考虑下面的游乐场

    package main

    import "fmt"

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

        messages <- "my msg"

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

    }

The code above will reach error 上面的代码将到达错误

fatal error: all goroutines are asleep - deadlock!

However 然而

if I change it to 如果我将其更改为

    package main

    import "fmt"

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

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

    }

It will work. 它会工作。

Is there a particular reason for this behavior? 这种行为是否有特定原因?

Shouldn't the code execute in a sequential manner in the first case so that by the time the select statement is reached, the msg will be passed and it will catch the case msg := <-messages ? 在第一种情况下,代码不应该以顺序方式执行,以便在到达select语句时,将传递msg并捕获msg := <-messages吗?

Shouldn't the code execute in a sequential manner in the first case so that by the time the select statement is reached, the msg will be passed and it will catch the case msg := <-messages ? 在第一种情况下,代码不应该以顺序方式执行,以便在到达select语句时,将传递msg并捕获msg:= <-messages吗?

The select statement is never reached, thats the problem in your first code. 永远不会到达select语句,这就是您的第一个代码中的问题。

The statement 该声明

messages <- "my msg"

Wants to push a string into the channel, but since you created a unbuffered channel 想要将字符串推入通道,但由于您创建了无缓冲通道

messages := make(chan string)

the goroutine keeps waiting for someone to actually read from the channel, so it can push the string to the channel. goroutine一直在等待某人实际从该通道读取,因此可以将字符串推送到该通道。 You can only push something to a unbuffered channel if there is somewhere a goroutine reading from it! 如果有goroutine读取内容,则只能将内容推送到无缓冲通道!

Try the first example with a buffered channel: 使用缓冲通道尝试第一个示例:

messages := make(chan string, 1)

It should work as you expected. 它应该按预期工作。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM