go的channel使用与总结
发布时间:2020-12-16 09:40:31 所属栏目:大数据 来源:网络整理
导读:channel用于主进程、协程之间的通信。 1.同步模式 channel默认为同步模式,即不创建缓冲区,发送和接收需要 一一配对 ,不然发送方会被一直阻塞,直到数据被接收。需要注意的是,同步的channel不能在一个协程中发送接收,因为会被阻塞而永远跑不到接收的语句
channel用于主进程、协程之间的通信。 1.同步模式 package main import "fmt" func main() { data := make(chan int) go func() { for d := range data {//通过range不断地处理data fmt.Println(d) } }() data <- 1//发送要放在接收协程跑起来后面,因为发送后会阻塞等待接收 data <- 2 data <- 3 close(data) } 或者用下面这种方法接收channel,如果!ok说明data被close: go func() { for { if d,ok := <-data; ok { fmt.Println(d) } } }() 2. 异步模式 package main import "fmt" func main() { data := make(chan int,3) canQuit := make(chan bool) //阻塞主进程,防止未处理完就退出 go func() { for d := range data {//如果data的缓冲区为空,这个协程会一直阻塞 fmt.Println(d) } canQuit <- true }() data <- 1 data <- 2 data <- 3 data <- 4 data <- 5 close(data) //用完需要关闭,否则goroutine会被死锁 <-canQuit //解除阻塞 } 3.select的使用 package main import "fmt" import "time" import "os" 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 main() { newReq := Request{ CmdID: CMD_USER_POS,Data: UserPos{ X: 10,Y: 20,},} go handler() req <- &newReq time.Sleep(2000 * time.Millisecond) save <- true close(req) <-quit } func handler() { for { select { case <-save: saveGame() case r,ok := <-req: if ok { onReq(r) } else { fmt.Println("req chan closed.") os.Exit(0) } } } } func init() { req = make(chan *Request,MAX_REQUEST_NUM) save = make(chan bool) quit = make(chan bool) } func saveGame() { fmt.Printf("Do Something With Save Game.n") quit <- true } func onReq(r *Request) { pos := r.Data.(UserPos) fmt.Println(r.CmdID,pos) } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |