tm := time.After(10 * time.Second)
for {
var activeWorker chan<- int
var activeValue int
if len(values) > 0 {
activeWorker = worker
activeValue = values[0]
}
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("Time out")
case <-tm:
fmt.Println("byte")
return
}
}
老师的例子中分别出现两种创建 <-chan Time
的方法,
tm
创建在循环体的外面,这个比较容易理解,也就是启动一个 携程然后,我们使用select
看他有没有送出值
而第2中在 case
中创建,这个我就不清楚了,每次for{}
在运行时每个case
都会看看是不是有值,要是没有就结束select
,而每次我们都创建一个新的定时器携程(可以理解成阻塞的发射器吧),在创建了新的<-chan Time
之后前一个<-chan Time
的携程岂不是没有地方接收了?由于在这一轮for
中的case
是一个新的<-chan Time
,新的<-chan Time
计时应该是也是以当前时间开始的,这么一来就算是超时那不也是检测不到了呀?然而事实上和我的预期有出入。
我的理解是不是出错了老师?
后我又换了种思路来考虑这个问题,也就是说此select
所有case
都是并行的执行的,那么这样一来考虑所有的case
都被阻塞<-chan Time
到时间后解除阻塞,这么思考就能符合输出的结果。但是这样又和default
和case
顺序的意义相冲突?他们的顺序是没有意义的吗?
下面是 time.After
函数的
func After(d Duration) <-chan Time {
return NewTimer(d).C
}
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
}
可以看到这个NewTimer
每次都make
了新的内存空间创建了一个全新的Timer