关于计算Select中获取资料的时长
来源:11-4 用select进行调度

憨憨Paul
2021-11-15
package main
import (
"fmt"
"math/rand"
"time"
)
func createWorker(id int) chan<- int {
c := make(chan int)
go worker(id, c)
return c
}
func worker(id int, c chan int) {
for n := range c {
fmt.Printf("Worker %d received %d\n", id, n)
}
}
// 构建器
func generator() chan int {
out := make(chan int)
go func() {
i := 0
// 间隔 150 ms
for ; ; time.Sleep(time.Duration(rand.Intn(150)) * time.Millisecond) {
// 发送数据
out <- i
i++
}
}()
return out
}
func main() {
var (
c1 = generator()
c2 = generator()
worker = createWorker(0)
n = 0
values = make([]int, 0)
// 添加定时器
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): // Question
fmt.Println("time out")
case <-tm: // 定时器时间到了就自动关闭
fmt.Println("bye")
return
}
}
}
对标记注解Question
产生的一些想法
虽然 Select
是对 channel
的非堵塞式接收处理方案
但是在没有 default 的情况下
Select 内部还是会把所有的资料都接收完毕再做操作
所以当 c1 & c2 & activeValue & tm
没有要传送资料时
整个 Select
将会处于停滞状态,
那么当时间超过800毫秒时
那么第四个 case
就将会接收到数据,从而执行对应的程式码
写回答
1回答
-
ccmouse
2021-11-15
select中所有的case会先被执行,然后再进行等待。
c1 & c2 & activeWorker(注意是Worker不是Value) & tm,它们的执行结果就是本身。
time.After(800 * time.Millisecond),这个也要先被执行,time.After函数返回一个chan Time。
好了,至此所有的执行结束,开始进入等待。如果800毫秒c1 & c2 & activeWorker & tm都没有等到/发送数据,那么此时就会在time.After函数返回的chan Time里收到数据,触发第4个case
00
相似问题