首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >选择和context.Context完成通道

选择和context.Context完成通道
EN

Stack Overflow用户
提问于 2020-12-06 20:02:02
回答 1查看 1.9K关注 0票数 5

我不明白Done()通道如何在context.Context中按预期工作。模块文档(以及使用它的源代码)依赖于以下模式:

代码语言:javascript
复制
select {
case <-ctx.Done():
    return ctx.Err()

case results <- result:
}

如果取消或超时了Done()的通道返回,并且Err()变量包含原因,则Context将关闭。

关于这一做法,我有两个问题:

  1. 当通道关闭时,select的行为是什么?什么时候和为什么要立案?没有作业这一事实与此有关吗?
  2. 根据语文参考资料: 如果一个或多个通信可以进行,则通过统一的伪随机选择来选择能够进行的单个通信。

如果选择是随机的,那么当Context被取消时,该模式如何保证我不会在管道中发送结果?我会理解,如果这些案例是按照声明顺序进行评估的(并且选择了关闭的通道案例)。

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

EN

回答 1

Stack Overflow用户

发布于 2020-12-06 20:13:23

本案:

代码语言:javascript
复制
case <-ctx.Done():

有通信操作:

代码语言:javascript
复制
<-ctx.Done()

这是从频道接收到的。规范:接收操作员:

关着的不营业的通道上的接收操作总是可以立即进行,在接收到任何先前发送的值之后,生成元素类型的零值

因此,当ctx.Done()返回的通道关闭时,可以立即进行接收。因此,控制流可以进入这种情况。

如果当上下文被取消时,另一个case (results <- result)也可以继续,那么随机地选择一个(伪),就无法保证它将是哪一个。

如果上下文已被取消,则不希望在results上发送值,请使用另一个非阻塞selectselect之前检查通道

代码语言:javascript
复制
select {
case <-ctx.Done():
    return ctx.Err()
default:
}

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

case results <- result:
}

注意,必须向第一个选择中添加一个default分支,否则它将被阻塞,直到上下文被取消。如果有一个default分支,并且上下文尚未取消,则选择default分支,因此控制流可以转到第二个select

见有关问题:

go选择语句的强制优先级

当涉及多个通道时,如何选择工作?

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/65172524

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档