请稍等 ...
×

采纳答案成功!

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

关于select的选择执行的问题

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干活。

0 回复 有任何疑惑可以回复我~
  • 提问者 weibo_隱懓_0 #1
    多谢
    回复 有任何疑惑可以回复我~ 2018-02-26 10:32:39
  • 提问者 weibo_隱懓_0 #2
    那我把下面的这定时select写进 goroutine里包装一下 是不是就可以了? 就不会被上面的for影响了
    回复 有任何疑惑可以回复我~ 2018-02-26 10:50:36
  • ccmouse 回复 提问者 weibo_隱懓_0 #3
    也可以
    回复 有任何疑惑可以回复我~ 2018-02-26 11:07:39
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信