我不明白Done()通道如何在context.Context中按预期工作。模块文档(以及使用它的源代码)依赖于以下模式:
select {
case <-ctx.Done():
return ctx.Err()
case results <- result:
}如果取消或超时了Done()的通道返回,并且Err()变量包含原因,则Context将关闭。
关于这一做法,我有两个问题:
select的行为是什么?什么时候和为什么要立案?没有作业这一事实与此有关吗?如果选择是随机的,那么当Context被取消时,该模式如何保证我不会在管道中发送结果?我会理解,如果这些案例是按照声明顺序进行评估的(并且选择了关闭的通道案例)。
如果我完全偏离了轨道,请从更好的角度向我解释。
发布于 2020-12-06 20:13:23
本案:
case <-ctx.Done():有通信操作:
<-ctx.Done()这是从频道接收到的。规范:接收操作员:
因此,当ctx.Done()返回的通道关闭时,可以立即进行接收。因此,控制流可以进入这种情况。
如果当上下文被取消时,另一个case (results <- result)也可以继续,那么随机地选择一个(伪),就无法保证它将是哪一个。
如果上下文已被取消,则不希望在results上发送值,请使用另一个非阻塞select在 select之前检查通道。
select {
case <-ctx.Done():
return ctx.Err()
default:
}
select {
case <-ctx.Done():
return ctx.Err()
case results <- result:
}注意,必须向第一个选择中添加一个default分支,否则它将被阻塞,直到上下文被取消。如果有一个default分支,并且上下文尚未取消,则选择default分支,因此控制流可以转到第二个select。
见有关问题:
https://stackoverflow.com/questions/65172524
复制相似问题