go select 语句中发送和接收操作之间的优先级规则

priority rule between sent and receive operation in a go select statement

go select 语句中发送和接收操作之间是否有优先级规则?

因为“发送”操作总是准备就绪,不像“接收”操作那样等待来自通道的东西,我总觉得“发送”将首先在 select.

我尝试了一些代码来测试发送和接收都准备就绪时会发生什么:

package main

import (
    "fmt"
    "time"
)

func main() {
    ch1 := make(chan string)
    ch2 := make(chan string)
    go goOne(ch1)
    go goTwo(ch2)

    time.Sleep(time.Second * 2)
    select {
    case ch2 <- "To goTwo goroutine":
    case msg1 := <-ch1:
        fmt.Println(msg1)
    }
}

func goOne(ch chan string) {
    ch <- "From goOne goroutine"
}

func goTwo(ch chan string) {
    msg := <-ch
    fmt.Println(msg)
}

结果似乎总是“From goOne goroutine”。所以似乎接收操作具有优先权。 但这是设计效果吗?还是发送者先被执行?我在文档中找不到信息

如果我希望接收操作具有优先级,我可以依赖它还是应该做其他事情?

谢谢!

Is there a priority rule between sent and receive operation in a go select statement?

没有。当有多个case同时就绪时,随机执行一个

Since a "send" operation is always ready

不正确。当另一端没有接收任何东西时,或者当缓冲通道的缓冲区已满时,发送操作可能会阻塞(即未准备好)。

Or could it happen that the sent got executed first?

是的,但是在 selected 这种情况下你可能看不到任何输出,因为你的程序在 main 中恢复执行并在 goTwo goroutine 实际打印任何内容之前立即退出。

If I want the receive operation to have the priority [...]

语句的 语义 是:“先准备好执行”。如果一种情况必须优先于另一种情况,请将另一种情况更改为 default(如果没有其他准备就绪,则运行):

    select {
    case msg1 := <-ch1:
        fmt.Println(msg1)
    default:
        ch2 <- "To goTwo goroutine"
    }