在一个 select 案例中从一个通道读取并写入另一个通道
Read from one channel and write to another within one select-case
考虑这个 Go 代码,它将立即调用 worker.DoWork()
,然后每分钟调用一次:
triggerChan := make(chan time.Time, 1)
triggerChan <- time.Now() // We don't want to wait a minute for the first call of worker.DoWork() to happen.
ticker := time.NewTicker(time.Minute)
defer ticker.Stop()
for {
select {
case triggerChan <- <-ticker.C:
case <-triggerChan:
worker.DoWork()
}
}
在第一个 select
之前将值写入 triggerChan
以将其定向到 case <-triggerChan
以便立即调用 worker.DoWork()
。但是,如果 ticker.C
已经有一个可用值(如果我们使用 time.Microsecond
而不是 time.Minute
之类的东西并不是那么不可能),会发生什么?运行时是否会看到 triggerChan <- <-ticker.C
会阻塞,或者它会愉快地软锁定而不知道 <-ticker.C
的结果正在尝试做什么?它是否意识到这种“从频道到频道”的情况?
select
根据 triggerChan
的状态决定,但是它首先计算发送操作的右侧表达式。
所以在进入时,它将等到 <-ticker.C returns。然后它会从通道中读取第一个值,然后写入它...
考虑这个 Go 代码,它将立即调用 worker.DoWork()
,然后每分钟调用一次:
triggerChan := make(chan time.Time, 1)
triggerChan <- time.Now() // We don't want to wait a minute for the first call of worker.DoWork() to happen.
ticker := time.NewTicker(time.Minute)
defer ticker.Stop()
for {
select {
case triggerChan <- <-ticker.C:
case <-triggerChan:
worker.DoWork()
}
}
在第一个 select
之前将值写入 triggerChan
以将其定向到 case <-triggerChan
以便立即调用 worker.DoWork()
。但是,如果 ticker.C
已经有一个可用值(如果我们使用 time.Microsecond
而不是 time.Minute
之类的东西并不是那么不可能),会发生什么?运行时是否会看到 triggerChan <- <-ticker.C
会阻塞,或者它会愉快地软锁定而不知道 <-ticker.C
的结果正在尝试做什么?它是否意识到这种“从频道到频道”的情况?
select
根据 triggerChan
的状态决定,但是它首先计算发送操作的右侧表达式。
所以在进入时,它将等到 <-ticker.C returns。然后它会从通道中读取第一个值,然后写入它...