美文网首页
golang for-select 优雅的退出

golang for-select 优雅的退出

作者: 夜空一起砍猩猩 | 来源:发表于2020-05-21 18:50 被阅读0次

    • 启动两个做为生产者的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 main
    
    import (
       // "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 main
    
    import (
        "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 main
    
    import (
        "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.haomeiwen.com/subject/cemtahtx.html