dqd3690 2014-04-06 13:59
浏览 35
已采纳

Go频道上的Noob

I'm trying to wrap my head around concurrency patterns in Go and was confused by this example from #69

package main

import "fmt"

func fibonacci(c, quit chan int) {
    x, y := 0, 1
    for {
        select {
        case c <- x:
            x, y = y, x+y
        case <-quit:
            fmt.Println("quit")
            return
        }
    }
}

func main() {
    c := make(chan int)
    quit := make(chan int)
    go func() {
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
        quit <- 0
    }()
    fibonacci(c, quit)
}

In particular, I don't see how

for i := 0; i < 10; i++ {
    fmt.Println(<-c)
 }

is supposed to work, since all we did was make the channel, and now we "receive" from it 10 times? I tried out other code where I create a channel and then try to receive from it right away and I always get an error, but this seems to work and I can't quite see how. Thanks for any help!

  • 写回答

2条回答 默认 最新

  • duanjia7607 2014-04-06 16:56
    关注

    I’m giving you a shorter version of the code above, which I think should be easier to understand. (I explain the differences below.) Consider this:

    // http://play.golang.org/p/5CrBSu4wxd
    package main
    
    import "fmt"
    
    func fibonacci(c chan int) {
        x, y := 0, 1
        for {
            c <- x
            x, y = y, x+y
        }
    }
    
    func main() {
        c := make(chan int)
        go fibonacci(c)
    
        for i := 0; i < 10; i++ {
            fmt.Println(<-c)
        }
    }
    

    This is a more straightforward version because your main function is clearly just printing 10 values from the channel, and then exiting; and there is a background goroutine that is filling the channel as long as a new value is needed.

    This alternate version drops the quit channel, because the background goroutine simply dies when main() finishes (no need to kill it explicitly in such a simple example).

    Of course this version also kills the use of select{}, which is the topic of #69. But seeing how both versions accomplish the same thing, except killing of the background goroutine, can perhaps be a good aid in understanding what select is doing.

    Note, in particular, that if fibonacci() had a time.Sleep() as its first statement, the for loop would hang for that much time, but would eventually work.

    Hope this helps!

    P.S.: Just realized this version is just a simpler version than #68, so I’m not sure how much it’ll help. Oops. :-)

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 嵌入式系统基于PIC16F882和热敏电阻的数字温度计
  • ¥15 cmd cl 0x000007b
  • ¥20 BAPI_PR_CHANGE how to add account assignment information for service line
  • ¥500 火焰左右视图、视差(基于双目相机)
  • ¥100 set_link_state
  • ¥15 虚幻5 UE美术毛发渲染
  • ¥15 CVRP 图论 物流运输优化
  • ¥15 Tableau online 嵌入ppt失败
  • ¥100 支付宝网页转账系统不识别账号
  • ¥15 基于单片机的靶位控制系统