go channel里的一点疑惑
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
main 在向
save
发完true
后,几乎立刻就结束了。main 一结束,整个程序就结束了,这个时候 saveGame 很可能还没有机会能后执行。handler
里的"req chan closed"
可能也还没有执行机会。<-quit
会等待quit
里的数据,而saveGame
会在执行完后向quit
发送数据。所以,这样可以保证 main 可能等到saveGame
执行结束,从而可以看到saveGame
的输出。并且使得"req chan closed"
可能有执行的机会。main 这个也是一个协程,和你的程序同步进行,也就是说,你不知道是你的协程先执行完,还是main函数执行完,如果你的协程先执行,那么main还是输出就是你想要的,但是如果是main函数先执行完,那么你的协程是执行了,但是并不会输出了。