选择默认通道竞争条件

https://play.golang.org/p/FMKxtVlTL5

为什么default:select语句中的程序会无限循环?

package main


import (

    "fmt"

    "strconv"

    "time"

)


var quit chan bool

var counter chan int


func 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)

}


蛊毒传说
浏览 145回答 1
1回答

隔江千里

当 aselect有 adefault时,它变成非阻塞的。引用规范:如果一个或多个通信可以进行,则通过统一的伪随机选择选择一个可以进行的通信。否则,如果存在默认情况,则选择该情况。如果没有默认情况,“select”语句会阻塞,直到至少有一个通信可以继续。如果没有default, theselect将等到它可以从 接收quit或发送counter,然后执行此操作,然后继续(再次通过for循环,除非它运行该return)。默认情况下,从不等待任何事情,并且每次可以运行时都会简单地运行,除非其他操作之一通过。selectdefault理论上程序还是一样的,在第六次打印“Send!”后退出。和“接收!”&nbsp;— 但它可能太忙于打印“默认!”&nbsp;数十亿次才能在合理的时间内到达那里。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go