go channel里的一点疑惑

发布于 2022-09-11 22:05:09 字数 1733 浏览 18 评论 0

package main

import (
    "fmt"
    "os"
    "time"
)

const (
    MAX_REQUEST_NUM = 10
    CMD_USER_POS = 1
)

var (
    save chan bool
    quit chan bool
    req chan *Request
)

type Request struct {
    CmdId int16
    Data interface{}
}

type UserPos struct {
    x int16
    y int16
}

func init() {
    req = make(chan *Request, MAX_REQUEST_NUM)
    save = make(chan bool)
    quit = make(chan bool)
}

func saveGame() {
    fmt.Println("Do something with Save Game")
    quit <- true
}

func onReq(r *Request)  {
    pos := r.Data.(UserPos)
    fmt.Println(r.CmdId, pos)
}

func handler() {
    for  {
        select {
        case _, ok := <- save:
            //fmt.Println("saving.......")
            if ok{
                saveGame()
            } else {
                fmt.Println("channel empty or closed")
            }
        case r, ok := <- req:
            if ok {
                onReq(r)
            } else {
                fmt.Println("req chan closed")
                os.Exit(0)
            }
        }
    }
}

func main()  {
    // 为什么要有quit, quit的作用是什么
    newReq := &Request{
        CmdId: CMD_USER_POS,
        Data: UserPos{
            x: 10,
            y: 20,
        },
    }
    go handler()
    req <- newReq
    time.Sleep(time.Millisecond * 200)

    save <- true
    close(req)
    <- quit
}

上面这段代码里,如果注释掉

quit <- true

<-quit

结果只能打印
1 {10 20}
, 若保留,则打印
1 {10 20}
Do something with Save Game
req chan closed
没太看懂这里quit的作用。
我的想法是,
正常给save<-true之后,应该打印Do something with Save Game啊
关闭req之后,也该有req chan closed打印啊
看来还是理解不到位,go小白,辛苦大神指导下

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

π浅易 2022-09-18 22:05:09

main 在向 save 发完 true 后,几乎立刻就结束了。main 一结束,整个程序就结束了,这个时候 saveGame 很可能还没有机会能后执行。handler 里的 "req chan closed" 可能也还没有执行机会。

<-quit 会等待 quit 里的数据,而 saveGame 会在执行完后向 quit 发送数据。所以,这样可以保证 main 可能等到 saveGame 执行结束,从而可以看到 saveGame 的输出。并且使得 "req chan closed" 可能有执行的机会。

明媚如初 2022-09-18 22:05:09

main 这个也是一个协程,和你的程序同步进行,也就是说,你不知道是你的协程先执行完,还是main函数执行完,如果你的协程先执行,那么main还是输出就是你想要的,但是如果是main函数先执行完,那么你的协程是执行了,但是并不会输出了。

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文