为了账号安全,请及时绑定邮箱和手机立即绑定

为什么下面的通道操作会死锁?即下游 <- <- 上游

为什么下面的通道操作会死锁?即下游 <- <- 上游

Go
ITMISS 2022-05-18 16:52:44
我有两个渠道,上游和下游。我的目标是从上游读取数据并将它们传递给下游。但是,当上下文被取消时,我想优雅地退出而不会出现死锁。我试图变得“聪明”并做了类似以下的事情。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 := <-upstreamdownstream <-val
查看完整描述

1 回答

?
米琪卡哇伊

TA贡献1998条经验 获得超6个赞

select 语句不是在<-upstream接收语句上运行,而是在downstream <-send 语句上运行。


在选择案例可以确定downstream <-发送语句是否准备好之前,它首先必须评估参数表达式,即<-upstream. 因为没有任何东西被发送到upstream,所以该评估被阻止。这意味着您根本不会接触到选定的案例。


等效的多行代码看起来像这样,这很明显为什么它不起作用。


val := <-upstream

select {

case <-ctx.Done():

    log.Println("context is killed")

case downstream <- val:

    log.Println("transferred value from upstream to downstream")

}


查看完整回答
反对 回复 2022-05-18
  • 1 回答
  • 0 关注
  • 98 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号