Go 在for循环死锁中选择';s

Go 在for循环死锁中选择';s,go,Go,为什么会出现以下僵局 package main import ( "fmt" ) var quit chan bool var buffer chan string func main() { buffer = make(chan string) quit = make(chan bool) go func() { i:=0 for { select { case <

为什么会出现以下僵局

package main

import (
    "fmt"
)
var quit chan bool
var buffer chan string

func main() {
        buffer = make(chan string)
    quit = make(chan bool)
    go func() {
        i:=0
        for {
            select {
            case <- quit:
                fmt.Println("Bye!")
                return
            default:
                fmt.Println(<-buffer)
            }
            i++
            fmt.Println(i)
        }
    }()
    buffer <- "Go!"
    quit <- true        // This line dead locks
    //buffer <- "Hello" // When I do this instead it works?
    //quit <- true      // Also when I don't quit it still exit's?
}
主程序包
进口(
“fmt”
)
陈波
var缓冲区chan字符串
func main(){
缓冲区=生成(chan字符串)
退出=制造(chan bool)
go func(){
i:=0
为了{
挑选{

case将select default子句更改为

        default:
            fmt.Println("waiting on <-buffer")
            fmt.Println(<-buffer)

将select default子句更改为

        default:
            fmt.Println("waiting on <-buffer")
            fmt.Println(<-buffer)

此代码不能保证正常工作。您可能会幸运,但显然您一直不走运。您可能会幸运,并且可能会发生以下情况:

假设我们有两个goroutine,A和B,其中A是运行
main
的goroutine,B是运行匿名函数的goroutine。可能会发生以下情况:

  • B:执行
    选择
    ;没有人在
    退出
    频道上写东西,所以执行
    默认
    案例

  • B:执行
    此代码不能保证正常工作。你可能会幸运,但显然你一直不走运。你可能会幸运,可能会发生以下情况:

    假设我们有两个goroutine,A和B,其中A是运行
    main
    的goroutine,B是运行匿名函数的goroutine。可能会发生以下情况:

    • B:执行
      选择
      ;没有人在
      退出
      频道上写东西,所以执行
      默认
      案例
    • B:执行主程序包 进口( “fmt” ) 陈波 var缓冲区chan字符串 func main(){ 缓冲区=生成(chan字符串) 退出=制造(chan bool) go func(){ i:=0 为了{ 挑选{ 包装箱
      主包装箱
      进口(
      “fmt”
      )
      陈波
      var缓冲区chan字符串
      func main(){
      缓冲区=生成(chan字符串)
      退出=制造(chan bool)
      go func(){
      i:=0
      为了{
      挑选{
      
      好的,谢谢,需要几分钟考虑一下,我没那么聪明:DGot it:)PS你可以补充一点,如果主出口是第一个,退出频道的例行程序并不重要,因为它会被杀死。我也忘了:谢谢,需要几分钟考虑一下,我不是那么聪明:DGot it:)PS,你也可以吗另外,如果主出口是第一个,退出频道的例行程序并不重要,因为它会被杀死。我也忘记了:D
      select {
          case <-quit:
              fmt.Println("Bye!")
              return
          case str := <-buffer:
              fmt.Println(str)
      }
      
      package main
      
      import (
          "fmt"
      )
      
      var quit chan bool
      var buffer chan string
      
      func main() {
          buffer = make(chan string)
          quit = make(chan bool)
      
          go func() {
              i := 0
              for {
                  select {
                  case <-quit:
                      fmt.Println("Bye!")
                      return
                  case v := <-buffer:
                      fmt.Println(v)
                  default:
                      // 这里也可能 block
                      // fmt.Println(<-buffer)
                  }
      
                  i++
                  fmt.Println(i)
              }
          }()
      
          buffer <- "Go!"
          quit <- true // This line dead locks
          //buffer <- "Hello" // When I do this instead it works?
          //quit <- true      // Also when I don't quit it still exit's?
      }