关于select的选择执行的问题
来源:11-4 用select进行调度

weibo_隱懓_0
2018-02-25
select 我的理解是看下面的哪个channel有数据进来了,谁先有数据就先调度谁
不知道我理解的对不。
但是这样就有个疑问了,老师在讲select的时候
select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case activeWorker <- activeValue: values = values[1:] case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return }
里面的time.After,tick,tm(timeout). 理论上是不是并不能保证实时执行?最终结果得看是否被调度到。
如果其他的channel的入通道的速度快于计时,那不就是并不能保证准时进行调度timeout或者其他计时channel了吗?
那么如何保证呢?
我想到的是把获取channel和计时相关的分开,用两个select进行调用,这样能保证计时准确实时生效了吧:
for { select { case n := <-c1: values = append(values, n) case n := <-c2: values = append(values, n) case activeWorker <- activeValue: values = values[1:] } select { case <-time.After(800 * time.Millisecond): fmt.Println("timeout") case <-tick: fmt.Println( "queue len =", len(values)) case <-tm: fmt.Println("bye") return } }
请问这样理解对吗?
写回答
1回答
-
select的时候的确谁先有数据就调度谁,一起来数据的话调度器会随机兼顾公平。这个例子里,比如tm有了数据,但是选择了其它分支,那tm里的之前数据仍然在,等下一次select很可能就选择了tm。当然我们所要做的是在select的分支里不要花太多时间。
当然这的确不是实时和准确的。通用编程语言其实无法做到准确和实时。
比如你的修改里面,上面第一个select干活部分如果多花了点时间,那下面就不准确了。即使通过某种方法为这个时间的操作独占一个线程,仍然会遇到操作系统的调度问题。
不过你的修改不错的确对实时性有一定改善。有一个小问题,在第二个select里面可以加入default分支。那样如果三个时间有关的channel都没有数据的话,它不会卡在这里而是直接去下一个for干活。
052018-02-26
相似问题