简体   繁体   English

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

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

Is there a priority rule between sent and receive operation in a go select statement? go select 语句中发送和接收操作之间是否有优先级规则?

Since a "send" operation is always ready, not like a "receive" operation that wait for something to come from the channel, I always have the feeling that the "send" will be executed first on a select.由于“发送”操作总是准备就绪,不像“接收”操作等待来自通道的东西,我总觉得“发送”将首先在 select 上执行。

I tried a little code to test what happens when both send and receive are ready:我尝试了一些代码来测试发送和接收都准备就绪时会发生什么:

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)
}

The result seems to always be "From goOne goroutine".结果似乎总是“From goOne goroutine”。 So it seems the receive operation has the priority.所以似乎接收操作具有优先权。 But is it by design effect?但这是设计效果吗? Or could it happen that the sent got executed first?还是发送者先被执行? I couldn't find the info in the doc我在文档中找不到信息

If I want the receive operation to have the priority, can I rely on that or should I do something else?如果我希望接收操作具有优先权,我可以依赖它还是应该做其他事情?

Thanks!谢谢!

Is there a priority rule between sent and receive operation in a go select statement? go select 语句中发送和接收操作之间是否有优先级规则?

No. When more than one case is ready at the same time, one at random is executed.不可以,当同时有多个case准备就绪时,随机执行一个。

Since a "send" operation is always ready因为“发送”操作总是准备好的

Not true.不对。 A send operation may just block (ie not ready) when nothing is receiving on the other side, or when a buffered channel's buffer is full.当另一端没有接收任何东西时,或者当缓冲通道的缓冲区已满时,发送操作可能会阻塞(即未准备好)。

Or could it happen that the sent got executed first?还是发送者先被执行?

Yes, but you may see no output when this case is selected because your program resumes execution in main and exits immediately before the goTwo goroutine can actually print anything. Yes, but you may see no output when this case is selected because your program resumes execution in main and exits immediately before the goTwo goroutine can actually print anything.

If I want the receive operation to have the priority [...]如果我希望接收操作具有优先级 [...]

The very semantics of a select statement are: "execute whichever is ready first". select 语句的语义是:“执行先准备好的”。 If one case must have priority over the other, change the other one to default (runs if nothing else is ready):如果一种情况必须优先于另一种情况,请将另一种情况更改为default (如果没有其他准备就绪则运行):

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

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

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