关于生成数据被“冲掉”的疑惑
来源:11-4 用select进行调度

Stonebangbang
2020-05-28
老师好关于数据被冲掉哪里有些疑惑烦请解答
for {
if hasValue {
activeWork = w
} else {
activeWork = nil
}
select {
case n = <-c1:
hasValue = true
case n = <-c2:
hasValue = true
case activeWork <- n:
hasValue = false
}
}
以视频中运行结果07为例,work打印0的时候sleep了,这个时候是不是可以说work阻塞了?main函数中的循环从c1和c2拿值,其实这个保证了两个gennerate没有阻塞,但是这个时候,c1或者c2收到值以后hasValue为true,下次循环的时候activeWork不为nil然后会选择到 activeWork <- n,但是这个时候work在sleep,此时程序是怎样一个状态,为什么1-6就会丢弃调,而不是阻塞在哪里等着work的sleep结束以后再打印呢?麻烦您详细解释下
2回答
-
我们看这个worker
func worker(id int, c chan int) {
for n := range c {
time.Sleep(time.Second)
fmt.Printf("Worker %d received %d\n" id, n)
}
}
注意这个range c就是从channel c收取下一个数据,除非c被 close。worker只有运行到这一行的时候才会从c里面去收数据,在其它行的时候不会。
首先,它从c收了第一个元素0,然后sleep 1秒。而此时generator正在不断的生成数据。main函数里的select中,虽然activeWorker非nil,但是case activeWork <- n:这个分支不会被选中。因为worker运行在sleep这行,而不是 range c这行。由于case n = <-c1:处没有保存n,所以1到6被丢弃了。
1秒后,sleep结束,Printf终于把手里这个0打印出来,也很快也结束。worker运行到range c这行,开始收数据,所以接下来的case activeWork <- n:很有可能被选中,此时这个n已经到了7。
022020-08-01 -
ccmouse
2020-06-03
抱歉隔了很多天才来回答你这个问题。不知什么原因这里标点符号没有了。还请同学重新编辑一下你的问题,或者编辑一下回复在这里也可以,我再来针对性的看。
022020-06-03
相似问题