为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

Go
慕工程0101907 2021-05-19 13:10:44
几个月前,我在考虑如何在Go中为RPC库实现可关闭的事件循环。我设法方便地关闭服务器,如下所示: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()}我发现此实现的问题在于它涉及超时,这意味着最小关闭时间比可能的要多2秒。有没有更惯用的方法来创建事件循环?
查看完整描述

1 回答

?
波斯汪

TA贡献1811条经验 获得超4个赞

我认为Go中的事件循环不必是循环。


在单独的goroutine中处理关闭和连接似乎更简单:


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

}

请注意,您也可以在不使用通道的情况下直接在“关闭”函数中关闭侦听器。我在这里所做的是使用Listener.Accept的错误返回值来促进例程间的通信。


如果在关闭和连接处理实现的某个时候需要保护要在回答时关闭的某些资源,则可以使用Mutex。但是通常可以避免这种情况。


查看完整回答
反对 回复 2021-05-24
  • 1 回答
  • 0 关注
  • 222 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信