请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

select timeout的问题

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(800 * time.Millisecond) 这个case是怎么判断的啊?第一个好理解,就是收数据,收到就匹配到,但是这个800ms是怎么个匹配法?它是什么时候开始计时的?还是说第一次匹配到开始计时,?这里有点懵,老师帮忙解答下,
还有就是加了case <-tick:这个之后就打不出timeout了,这是为什么呢?我把800ms改成和tick一样都是1s 也不行,按理,这两个都是1秒的话,任何一个应该都可能被执行到吧?,

正在回答 回答被采纳积分+3

1回答

jierong 2019-07-10 17:11:37

1. https://img1.sycdn.imooc.com//szimg/5d25a8e00001ad3a07890211.jpg

time.After(d Duration) 返回值是一个chan Time, case <-time.After(800 * time.Millisecond) 如果没有接收到数据就是nil,就不会执行,如果接收到数据就执行。

func generator() <-chan int {
  out := make(chan int)
  go func() {
     i := 0
     for {
        time.Sleep(time.Duration(rand.Intn(1500)) * time.Millisecond)
        out <- i
        i++
     }
  }()
  return out
}

上面代码使用的是time.Duration(rand.Intn(1500)) * time.Millisecond如果时间低于800ms,case <-time.After(800 * time.Millisecond)将不会被执行,并且虽然goroutine是非抢占的,但是fmt.Println()是抢占式的,在10s内所有的fmt.Println()将抢占线程进行输出,fmt.Println("timeout")未必能够抢到线程。

2. case <-tick:这个之后就打不出timeout了,这个问题在第一个问题中已经说了,这个看fmt.Println()谁先抢到线程,抢到线程的就将打印。

0 回复 有任何疑惑可以回复我~
  • 提问者 bbmouse #1
    这里我的疑问其实是在case, 比如我的图上有6个case, 这6个应该只会匹配一个,那是按照从上到下的顺序判断吗?比如第一个case是否满足,不满足就判断第二个,如果是这样的话,只有判断到第四个case时,
    time.After(800 * time.Millisecond) 这一句才会被执行,然后开始计时,800ms后送出一个时间,假设是这样的话,这个时候它是否在开始计时之后又马上继续下面case的判断呢?
    但是估计不是这样判断的,比如c2,c1都进数据了(c2先到),但是这时候才开始第一个case判断,发现有数据,就不进行其余case的判断了,所以我猜这里的case是每次select时候,同时在判断,也就是每一次select, time.After(800 * time.Millisecond)这句话就会开始计时,总之就是这个case的判断机制好像和一般语言的不一样,所以搞的我有点晕,不知道我的猜测对不对,不过还是感谢你的解答 :)
    回复 有任何疑惑可以回复我~ 2019-07-10 17:39:32
  • jierong #2
    select中的case如果都满足条件的话,是随机选择的,这个在视频里面老师有说的。
    回复 有任何疑惑可以回复我~ 2019-07-10 18:45:54
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信