• select+chan控制goroutine结束


    1 一旦向chan中写入值了,select就执行之前阻塞的该通道,执行完后,再执行return,结束goroutine,

    func main() {
        stop := make(chan bool)
    
        go func() {
            for {
                select {
                case <-stop:
                    fmt.Println("监控退出,停止了...")
                    return
                default:
                    fmt.Println("goroutine监控中...")
                    time.Sleep(2 * time.Second)
                }
            }
        }()
    
        time.Sleep(10 * time.Second)
        fmt.Println("可以了,通知监控停止")
        stop<- true
        //为了检测监控过是否停止,如果没有监控输出,就表示停止了
        time.Sleep(5 * time.Second)
    
    }
    View Code

    注意select执行的时候是单线程,即如果只有case,要等每个case后的chan运行完,它才会去判断要执行那个case,所以尽量不要以自定义函数的形式返回chan,

    package main
    import (
        "context"
        "fmt"
        "sync"
        "time"
    )
    var res = make(map[string]string)
    var rw sync.RWMutex
    func writeMap(key string) (chan int){
        rw.Lock()
        res[key] = (key + " 网站爬虫结果")
        rw.Unlock()
        c := make(chan int, 1)
        c <- 0
        time.Sleep(time.Second * 10)
        return c
    }
    func doSomething(ctx context.Context, key string) {
        select {
        case <-ctx.Done():
            fmt.Println(key + "超时了,爬取未完成")
        case <- writeMap(key):
            fmt.Println(key + "网站爬取完成")
        }
    }
    func main() {
        var url = []string{
            "www.baidu.com",
            "www.123.com",
            "www.456.com",
        }
        for _, num := range url {
            //ctx, cancel := context.WithTimeout(context.Background(), time.Millisecond*5)
            ctx, _ := context.WithTimeout(context.Background(), time.Second * 1)
            //defer cancel()
          go doSomething(ctx, num)
        }
        time.Sleep(time.Second * 5)
        fmt.Println(res)
    }
    View Code

    通过下面这个程序可以更清晰的看出来,

    func test()(chan int){
        time.Sleep(time.Second * 5)
        res := make(chan int, 1)
        res <- 1
        return res
    }
    func main(){
        c := make(chan int, 1)
        c <- 1
        select {
        case <- c:
            fmt.Println("停顿5秒后才输出:aaa")
        case <- test():
            fmt.Println("bbb")
        }
    }
    View Code

    ttt

  • 相关阅读:
    linux下tomcat权限的问题
    树莓派安装Tomcat服务器
    Javascript基础——Object对象和Object原型对象
    electron
    ES6-21:编程风格、ECMAScript规格
    番外篇01:angularJS最佳实战
    ES6-18:class类及其继承
    ES6-10:Promise
    ES6-09:新增API—Proxy、Reflect
    ES6-08:新增数据结构—Set、WeakSet、Map、weakMap
  • 原文地址:https://www.cnblogs.com/xxswkl/p/14219706.html
Copyright © 2020-2023  润新知