初级会员
  • 第 74351 位会员
  • visli
  • 2022-06-28 15:24:51
  • Offline
  • 19 62

最近发布的文章

    暂无

最近分享的资源

    暂无

最近发布的项目

    暂无

最近的评论

  • @buscoop 最终方案就是1楼的办法。 另外,我最初的这个方案,似乎也不会报race问题,这是令我困惑的。 ``` func NewSrv() { ln, err := net.ListenTCP() defer ln.Close() ... go func() { <- exitChann ln.Close() } for { c, err:= ln.Accept() .... } } ```
  • @xwszt</a> , 最初是用channel来通知关闭的。外部goroutine close掉这个channel来通知。但这样需要在创建listener的协程中另起一个协程来监听这个channel。多个listener就起了多个监听的协程,感觉浪费。 大致代码如下: ``` func NewSrv() { ln, err := net.ListenTCP() defer ln.Close() ... go func() { <- exitChann ln.Close() } for { c, err:= ln.Accept() .... } } ``` 现在改成了1楼的建议: ``` func NewSrv() { ln, err := net.ListenTCP() defer ln.Close() ... for { select { case <- exitChann: return default: ln.SetDeadlin() c, err := ln.Accept() .... } } } ```" name="content" class="comment-textarea" rows="8" style="width: 100%;"><a href="/user/xwszt" title="@xwszt">@xwszt</a> , 最初是用channel来通知关闭的。外部goroutine close掉这个channel来通知。但这样需要在创建listener的协程中另起一个协程来监听这个channel。多个listener就起了多个监听的协程,感觉浪费。 大致代码如下: ``` func NewSrv() { ln, err := net.ListenTCP() defer ln.Close() ... go func() { <- exitChann ln.Close() } for { c, err:= ln.Accept() .... } } ``` 现在改成了1楼的建议: ``` func NewSrv() { ln, err := net.ListenTCP() defer ln.Close() ... for { select { case <- exitChann: return default: ln.SetDeadlin() c, err := ln.Accept() .... } } } ``` 问题的关键是listener非线程安全的,但又不好用加锁等方法来做同步
  • @xwszt 其实最初没把Listener做成全局变量,也不存在争用问题。前天在做代码审查时,发现一个专门处理服务关闭事件的协程,基本是空闲的,而项目里有许多Listener,就想把这些Listener都统一到这个协程里来作通知关闭管理,所以才改成全局变量的。
  • @jan-bar 谢谢。目前只有这个办法了。