doufen3838 2012-11-22 07:17
浏览 55
已采纳

在Go中侦听事件的惯用方法是什么?

A few months ago I was thinking how to implement a closable event loop in Go, for an RPC library. I managed to facilitate closing the server like so:

type Server struct {
    listener net.Listener
    closeChan chan bool
    routines sync.WaitGroup
}

func (s *Server) Serve() {
    s.routines.Add(1)
    defer s.routines.Done()
    defer s.listener.Close()

    for {
        select {
            case <-s.closeChan:
                // close server etc.
            default:
                s.listener.SetDeadline(time.Now().Add(2 * time.Second))
                conn, _ := s.listener.Accept()
                // handle conn routine
        }
    }
}

func (s *Server) Close() {
    s.closeChan <- true // signal to close serve routine
    s.routines.Wait()
}

The problem that I've found with this implementation is it involves a timeout, which means minimum close time is 2 seconds more than it could be. Is there a more idiomatic method of creating an event loop?

  • 写回答

1条回答 默认 最新

  • du42561 2012-11-22 07:34
    关注

    I don't think that event loops in Go need to be loops.

    It would seem simpler to handle closing and connections in separate goroutines:

    go func() {
        <-s.closeChan
        // close server, release resources, etc.
        s.listener.Close()
    }()
    for {
        conn, err := s.listener.Accept()
        if err != nil {
             // log, return
        }
        // handle conn routine
    }
    

    Note that you might also close the listener directly in your Close function without using a channel. What I have done here is used the error return value of Listener.Accept to facilitate inter-routine communication.

    If at some point of the closing and connection handling implementations you need to protect some resources you're closing while you're answering, you may use a Mutex. But it's generally possible to avoid that.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 执行 virtuoso 命令后,界面没有,cadence 启动不起来
  • ¥50 comfyui下连接animatediff节点生成视频质量非常差的原因
  • ¥20 有关区间dp的问题求解
  • ¥15 多电路系统共用电源的串扰问题
  • ¥15 slam rangenet++配置
  • ¥15 有没有研究水声通信方面的帮我改俩matlab代码
  • ¥15 ubuntu子系统密码忘记
  • ¥15 信号傅里叶变换在matlab上遇到的小问题请求帮助
  • ¥15 保护模式-系统加载-段寄存器
  • ¥15 电脑桌面设定一个区域禁止鼠标操作