代码之家  ›  专栏  ›  技术社区  ›  Grant

goroutines有高空闲唤醒电话

  •  2
  • Grant  · 技术社区  · 2 年前

    我正在使用GoLang使用goroutines同时运行两个websocket客户端(一个用于私有数据,一个用于公共数据)。表面上看,一切似乎都很顺利。两个客户端都接收从websocket服务器传输的数据。不过,我相信我可能设置了错误,因为当我检查活动监视器时,我的程序始终有500到1500次空闲唤醒,并且使用了>200%的CPU。对于像两个websocket客户端这样简单的东西来说,这似乎并不正常。

    我把代码放在了代码片段中,这样就不需要太多的阅读(希望这能让你更容易理解),但是如果你需要完整的代码,我也可以发布。下面是我的主func中运行ws客户端的代码

    comms := make(chan os.Signal, 1)
    signal.Notify(comms, os.Interrupt, syscall.SIGTERM)
    ctx := context.Background()
    ctx, cancel := context.WithCancel(ctx)
    var wg sync.WaitGroup
    
    wg.Add(1)
    go pubSocket.PubListen(ctx, &wg, &activeSubs, testing)
    wg.Add(1)
    go privSocket.PrivListen(ctx, &wg, &activeSubs, testing)
    
    <- comms
    cancel()
    wg.Wait()
    

    下面是客户端如何运行go例程的代码

    func (socket *Socket) PubListen(ctx context.Context, wg *sync.WaitGroup, subManager *ConnStatus, testing bool) {
        defer wg.Done()
        for {
            select {
            case <- ctx.Done():
                log.Println("closing public socket")
                socket.Close()
                return
            default:
                socket.OnTextMessage = func(message string, socket Socket) {
                    log.Println(message)
                    pubJsonDecoder(message, testing)
                    //tradesParser(message);
                }
            }
        }
    }
    
    func (socket *Socket) PrivListen(ctx context.Context, wg *sync.WaitGroup, subManager *ConnStatus, testing bool) {
        defer wg.Done()
        for {
            select {
            case <- ctx.Done():
                log.Println("closing private socket")
                socket.Close()
                return
            default:
                socket.OnTextMessage = func(message string, socket Socket) {
                    log.Println(message)
                }
            }
        }
    }
    

    你知道为什么空闲的起床时间这么高吗?我应该使用多线程而不是并发吗?提前感谢您的帮助!

    1 回复  |  直到 2 年前
        1
  •  2
  •   wasmup Prog_is_life    2 年前

    你在浪费CPU( 多余循环 ):

      for {
           // ...
            default:
            // High CPU usage here.
            }
        }
    

    试试这样:

     func (socket *Socket) PubListen(ctx context.Context, wg *sync.WaitGroup, subManager *ConnStatus, testing bool) {
        defer wg.Done()
        defer socket.Close()
    
        socket.OnTextMessage = func(message string, socket Socket) {
            log.Println(message)
            pubJsonDecoder(message, testing)
            //tradesParser(message);
        }
    
        <-ctx.Done()
        log.Println("closing public socket")
    }
    
    func (socket *Socket) PrivListen(ctx context.Context, wg *sync.WaitGroup, subManager *ConnStatus, testing bool) {
        defer wg.Done()
        defer socket.Close()
    
        socket.OnTextMessage = func(message string, socket Socket) {
            log.Println(message)
        }
    
        <-ctx.Done()
        log.Println("closing private socket")
    }
    

    这也可能有助于:
    https://github.com/gorilla/websocket/blob/master/examples/chat/client.go