1. 首页
  2. 主题
  3. Go问与答

select超时优先级

LovesAsuna · · 3800 次点击
# select中的超时优先级 > select中可以通过在case设置time.After进行超时,但为什么超时操作会比其他的case优先级低?如果其他的case会运行那么超时就不作数。为此我在主协程模拟了一个超时 ```go func main() { channel := make(chan interface{}, 100) delay := make(chan interface{}) for i := 0; i < 10; i++ { channel <- 1 } go func() { for { select { case <-delay: fmt.Println("超时") case i := <-channel: fmt.Println(i) time.Sleep(time.Second) } } }() time.After(3 * time.Second) delay <- 1 for { } } ``` 结果打印如下 ``` 1 超时 1 1 1 1 1 1 ``` * 这样的结果很符合我对"超时"的认知,函数的超时只取决于调用者本身而不是取决于函数中的状态。 --- > 而正常的select却不是这样的,我做了这样的对比只是印证了time.After内部的实现原理与我写的不一样 查看源码可以发现time.After实际上是调用了NewTimer,NewTimer的源码是这样的 ```go func NewTimer(d Duration) *Timer { c := make(chan Time, 1) t := &Timer{ C: c, r: runtimeTimer{ when: when(d), f: sendTime, arg: c, }, } startTimer(&t.r) return t } ``` * 可以看出time.After其实是返回了NewTimer内部定义的Timer的C。 * 而我认为问题的关键就在于下面的startTimer,其中肯定有往C输入内容的管道。往C输入内容的时机就是问题的答案。 * 由于源码过于复杂比较难分析,因此想问问这个优先级的原因出在哪里?
我认为你的代码有2点问题: 第一,你的3秒超时效果并没有达到, 正确的用法是`tc := time.After(time.Second * 3); &lt;-tc;delay &lt;- 1` 第二, select那里, delay和channel都有数据的时候,select是随机选择一个执行,而不保证delay优先执行。你的channel是提前放入10个数据,实际运行的结果是不能保证到了超时就能打印"超时"
#1
更多评论
你的代码我愣是没看懂...... 正常for中的select至少会有个分支进行return,以退出这个处理循环。 如果你要超时后不继续读数据的话 至少应该是 ```go go func() { for { select { case &lt;-delay: fmt.Println(&#34;超时&#34;) return case i := &lt;-channel: fmt.Println(i) time.Sleep(time.Second) } } }() ```
#2
不存在优先级吧,select 多个 case 同时满足的话,会随机触发一个
#3

用户登录

没有账号?注册

今日阅读排行

    加载中

一周阅读排行

    加载中