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

选择默认通道竞争条件

选择默认通道竞争条件

Go
蛊毒传说 2022-01-17 10:51:09
https://play.golang.org/p/FMKxtVlTL5为什么default:select语句中的程序会无限循环?package mainimport (    "fmt"    "strconv"    "time")var quit chan boolvar counter chan intfunc main() {    counter = make(chan int)    quit = make(chan bool)    go func() {        i := 0        for {            i++            select {            case <-quit:                fmt.Println("Bye!")                return            case counter <- i:                fmt.Println("Send! " + strconv.Itoa(i))            default:                fmt.Println("Default! " + strconv.Itoa(i))            }        }    }()    fmt.Println("Receive! " + strconv.Itoa(<-counter))    fmt.Println("Receive! " + strconv.Itoa(<-counter))    fmt.Println("Receive! " + strconv.Itoa(<-counter))    fmt.Println("Receive! " + strconv.Itoa(<-counter))    fmt.Println("Receive! " + strconv.Itoa(<-counter))    fmt.Println("Receive! " + strconv.Itoa(<-counter))    quit <- true    time.Sleep(1 * time.Second)}
查看完整描述

1 回答

?
隔江千里

TA贡献1906条经验 获得超10个赞

当 aselect有 adefault时,它变成非阻塞的。引用规范:

如果一个或多个通信可以进行,则通过统一的伪随机选择选择一个可以进行的通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,“select”语句会阻塞,直到至少有一个通信可以继续。

如果没有default, theselect将等到它可以从 接收quit或发送counter,然后执行此操作,然后继续(再次通过for循环,除非它运行该return)。默认情况下,从不等待任何事情,并且每次可以运行时都会简单地运行,除非其他操作之一通过selectdefault

理论上程序还是一样的,在第六次打印“Send!”后退出。和“接收!” — 但它可能太忙于打印“默认!” 数十亿次才能在合理的时间内到达那里。


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

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信