美文网首页
go协程携程空跑问题(协程数量异常增长)

go协程携程空跑问题(协程数量异常增长)

作者: Ucan先生 | 来源:发表于2019-07-22 23:26 被阅读0次

    协程空跑问题 ?

    问题的发现:

    周末在使用go 语言websocket做了一个简易的服务端,当时为了测试使用chrome多开tab与服务器端通信?又一时好奇想探索,到底服务端开启了多少携程的数量,使用了pprof观察服务端的资源消耗情况。大抵在一个wsHandler里面使用了4个携程来异步处理读写,使用两个channel进行读写数据的收发。观察到当我关闭浏览器tab窗口的时候,goroutine的数量竟然没有减少,进行了一些探究。

    什么是协程空跑:

    在父协程中开启子协程,父协程如果不阻塞,父协程执行完毕后,如果go的进程也可以说main协程没有结束,子协程如果还运行有任务还会继续执行,如果是个死循环?。go语言中,没有父子协程的概念,除了主协程其余协程都是平行概念。

    危害性:

    对于常驻服务,每次连接都会产生一些空跑的常驻进程,时间久了内存和cpu占用就是问题。

    代码示例:

    package main
    
    import (
        "fmt"
        "net/http"
        _ "net/http/pprof"
    )
    func main()  {
        http.HandleFunc("/",handler)
        http.ListenAndServe(":8081",nil);
    }
    
    func handler(w http.ResponseWriter,r *http.Request)  {
        go test()
        w.Write([]byte("Hello World"))
    }
    
    //三个空跑协程,每连接一次,都会生成三个空跑协程。
    func test()  {
        go empty()
        go empty()
        go empty()
    }
    
    func empty()  {
        i:=0;
        for {
            fmt.Println("int---",i);
            i++;
        }
    }
    
    初始化状态4个协程 每连接一次增加3个协程

    周末碰到典型错误:

    func (conn *Connection) ReadLoop() {
        fmt.Println(conn.WsConn.RemoteAddr())
        for {
            if _, data, err := conn.WsConn.ReadMessage(); err == nil {
                select {
                case conn.readChan <- data:
                case <-conn.closeChan:
                    conn.CloseConnetion();
                    return;  // not break not break not break
                }
            } else {
                conn.CloseConnetion();
                return;  // not break not break not break
            }
        }
    }
    

    相关文章

      网友评论

          本文标题:go协程携程空跑问题(协程数量异常增长)

          本文链接:https://www.haomeiwen.com/subject/stkxmftx.html