zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    WAF与IPS的区别总结
    web后门排查与高效分析web日志技巧
    如何做一名好的web安全工程师?
    从“黑掉Github”学Web安全开发
    DNS劫持
    万网上如何将IP和申请的域名绑定
    如何申请网站域名
    什么是域名?什么网站名?什么是URL?
    myeclipse svn 插件去除已经保存的密码方法
    SVN中检出 和 导出 的区别
  • 原文地址:https://www.cnblogs.com/xxswkl/p/14219706.html
Copyright © 2011-2022 走看看