我有两个渠道,上游和下游。我的目标是从上游读取数据并将它们传递给下游。但是,当上下文被取消时,我想优雅地退出而不会出现死锁。
我试图变得“聪明”并做了类似以下的事情。
func main() {
upstream := make(chan struct{})
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-time.After(5 * time.Second)
cancel()
}()
// Buffered downstream ensures no blocking in this scenario
downstream := make(chan struct{}, 1)
select {
case <-ctx.Done():
log.Println("context is killed")
case downstream <- <-upstream:
log.Println("transferred value from upstream to downstream")
}
}
然后我陷入了僵局。但是,如果我不再懒惰并执行以下操作,
func main() {
upstream := make(chan struct{})
ctx, cancel := context.WithCancel(context.Background())
go func() {
<-time.After(5 * time.Second)
cancel()
}()
// Buffered downstream ensures no blocking in this scenario
downstream := make(chan struct{}, 1)
select {
case <-ctx.Done():
log.Println("context is killed")
case val := <-upstream:
downstream <-val
log.Println("transferred value from upstream to downstream")
}
}
它完美地退出,没有死锁。请您赐教,两者之间的主要区别是什么
downstream <- <-upstream
和
val := <-upstream
downstream <-val
米琪卡哇伊
相关分类