- 启动两个做为生产者的go-routing,
- 分别将数据生产的数据写入两个带缓冲的通道cha1,ch2
- 分别模拟在Main go-routing和 sub go-routing中通过for-select循环读取两个通道的值并打印
- 通过3种方式优雅的退出main go-routing
exit for-select in go-routing
https://play.golang.org/p/Ar4389-87QE
package mainimport ( // "time" "fmt")func produce(id int, ch chan string, quitSub chan int){ for i:=0;i< 10;i++{ ch <- fmt.Sprintf("msg:%d:%d",id,i) } quitSub <- id}func main() { c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1 c2 := make(chan string, 1) quitForSelect := make(chan int, 2) //用于通知退出for select循环 quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕 quitMain := make(chan bool) //阻塞main gorouting,等待for select 处理完成 go produce(1, c1, quitForSelect) go produce(2, c2, quitForSelect) go func(){ for { //使用select来等待这两个通道的值,然后输出 select { case msg1 := <- c1: fmt.Println(msg1) case msg2 := <- c2: fmt.Println(msg2) case q := <- quitForSelect: fmt.Println("got quit tag for Gorouting id:", q) quitTag = append(quitTag,q) if len(quitTag) == 2{ fmt.Println("end to quit Main ") quitMain <- true } } } }() <-quitMain fmt.Println("exit from main")}
exit for-select by "break" in Main go-routing
https://play.golang.org/p/vEUvAslRqVw
package mainimport ( "fmt")func produce(id int, ch chan string, quitSub chan int) { for i := 0; i < 10; i++ { ch <- fmt.Sprintf("msg:%d:%d", id, i) } quitSub <- id}func main() { c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1 c2 := make(chan string, 1) quitForSelect := make(chan int, 2) //用于通知退出for select循环 quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕 go produce(1, c1, quitForSelect) go produce(2, c2, quitForSelect)ForEnd: for { //使用select来等待这两个通道的值,然后输出 select { case msg1 := <-c1: fmt.Println(msg1) case msg2 := <-c2: fmt.Println(msg2) case q := <-quitForSelect: fmt.Println("got quit tag for Gorouting id:", q) quitTag = append(quitTag, q) if len(quitTag) == 2 { fmt.Println("end to quit Main ") break ForEnd } } } fmt.Println("exit from main")}
exit for-select by "goto" in Main go-routing
https://play.golang.org/p/GKD_NYpoMdT
package mainimport ( "fmt")func produce(id int, ch chan string, quitSub chan int) { for i := 0; i < 10; i++ { ch <- fmt.Sprintf("msg:%d:%d", id, i) } quitSub <- id}func main() { c1 := make(chan string, 1) //定义两个有缓冲的通道,容量为1 c2 := make(chan string, 1) quitForSelect := make(chan int, 2) //用于通知退出for select循环 quitTag := []int{} //用于读取和存储quitForSlect通道的两个值,保证两个product都写入完毕 go produce(1, c1, quitForSelect) go produce(2, c2, quitForSelect) for { //使用select来等待这两个通道的值,然后输出 select { case msg1 := <-c1: fmt.Println(msg1) case msg2 := <-c2: fmt.Println(msg2) case q := <-quitForSelect: fmt.Println("got quit tag for Gorouting id:", q) quitTag = append(quitTag, q) if len(quitTag) == 2 { fmt.Println("end to quit Main ") goto ForEnd } } }ForEnd: fmt.Println("go to here from for-select") fmt.Println("exit from main")}
文章来源:智云一二三科技
文章标题:golang for-select 优雅的退出
文章地址:https://www.zhihuclub.com/520.shtml