go - 选择和上下文。上下文完成 channel

标签 go concurrency channel

我不明白 Done() 是怎么回事 channel context.Context可以按预期工作。模块文档(和使用它的源代码)依赖于这种模式:

select {
case <-ctx.Done():
    return ctx.Err()

case results <- result:
}
channel 返回 Done()如果 Context 则关闭被取消或超时,Err()变量持有原因。
关于这种方法,我有两个问题:
  • select 的行为是什么? channel 何时关闭?何时以及为何进入案件?没有分配的事实是否具有相关性?
  • 根据语言引用:

    If one or more of the communications can proceed, a single one that can proceed is chosen via a uniform pseudo-random selection.


    如果选择是随机的,那么该模式如何保证我不会在 Context 时将结果发送到管道中?被取消?我会理解这些案例是否按申报顺序进行评估(并选择了封闭 channel 案例)。

  • 如果我在这里完全偏离轨道,请从更好的角度向我解释。

    最佳答案

    这个案例:

    case <-ctx.Done():
    
    有通讯操作:
    <-ctx.Done()
    
    这是来自 channel 的接收。 Spec: Receive operator:

    A receive operation on a closed channel can always proceed immediately, yielding the element type's zero value after any previously sent values have been received.


    所以当ctx.Done()返回的 channel 已关闭,从它的接收可以立即进行。因此控制流可以进入这种情况。
    如果其他case ( results <- result ) 也可以在上下文被取消时继续,随机选择(伪)一个,不能保证它将是哪一个。
    如果您不想在 results 上发送值如果上下文已被取消,请检查 ctx.Done() channel 之前 select与另一个非阻塞 select :
    select {
    case <-ctx.Done():
        return ctx.Err()
    default:
    }
    
    select {
    case <-ctx.Done():
        return ctx.Err()
    
    case results <- result:
    }
    
    请注意,您必须添加 default分支到第一个选择,否则它将阻塞直到上下文被取消。如果有 default分支和上下文尚未取消,default选择了分支,因此控制流可以转到第二个 select .
    查看相关问题:
    Force priority of go select statement
    How does select work when multiple channels are involved?

    关于go - 选择和上下文。上下文完成 channel ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65172524/

    相关文章:

    python - 为什么 Python 的 multiprocessing.Queue 不阻塞

    audio - .wav 文件格式中的 channel 是什么?播放 wav 文件时所有 channel 是否同时播放?

    go - 坚持 Go 并发

    xml - 使用 Go 解析 XML 时遇到问题

    c++ - 在go中删除内存

    java - 无锁并发栈实现

    wcf - 自托管 WCF 服务主机/WebServiceHost 并发/性能设计选项 (.NET 3.5)

    golang sync.WaitGroup 永远不会完成

    arrays - 如何使用数组填充结构 slice ?

    c# - .NET 中的 Erlang 风格的轻量级进程