几个月前,我在考虑如何在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。但是通常可以避免这种情况。
- 1 回答
- 0 关注
- 222 浏览
添加回答
举报
0/150
提交
取消