select、定时器

应用场景举例:
一个任务管道满了,再往里面塞就塞不进去了,浏览器刷不出来了。用户即便关了浏览器可能依然在阻塞......

package main

import "fmt"import "time"func main() {    var ch chan int
    ch = make(chan int, 10)
    ch2 := make(chan int, 10)    go func() {        var i int
        for {
            ch <- i
            time.Sleep(time.Second)
            ch2 <- i * i
            time.Sleep(time.Second)
            i++
        }
    }()    for {        select {        //这个case如果不能从ch中获取数据,则会立即走下一个
        case v := <-ch:
            fmt.Println(v)            //这个case如果不能从ch2中获取数据,则会立即走下一个
        case v := <-ch2:
            fmt.Println(v)        //然而这样写可能有内存泄漏! 
        case <-time.After(time.Second):
            fmt.Println("get data timeout")
            time.Sleep(time.Second)        default:
            fmt.Println("===================")
            time.Sleep(time.Second)
        }
    }
}

上面的写法可能会有内存泄漏!

package mainimport (
    "fmt"
    "runtime"
    "time")

func main() {
    num := runtime.NumCPU()
    runtime.GOMAXPROCS(num - 1)    for i := 0; i < 16; i++ {        go func() {            for {                //每秒执行一次
                t := time.NewTicker(time.Second)                select {                case <-t.C:
                    fmt.Println("timeout")
                }                //一定要关闭
                t.Stop()
            }
        }()
    }

    time.Sleep(time.Second * 100)
}

go官方文档的建议:
goroutine/channel(select、定时器)


猜你喜欢

转载自blog.51cto.com/5660061/2372096