美文网首页
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