1 回答
TA贡献1853条经验 获得超9个赞
你的代码很好。您甚至可以更进一步并替换:
s.acceptChannel <-&Connection{tcpConn: rw, .... }
和:
go handleConnection(&Connection{tcpConn: rw, .... })
正如评论中提到的,例程不是系统线程,它们是由 Go 运行时管理的轻量级线程。当您为每个连接创建一个例程时,您可以轻松地使用更容易实现的阻塞操作。Go 运行时然后为您选择例程,因此您正在寻找的行为只是其他地方,埋在语言中。你看不到它,但它无处不在。
现在,如果您需要更复杂的东西,并且根据我们的对话,实现类似于带有超时选择的东西,您将完全按照您的建议执行:将所有新连接推送到一个通道并使用计时器对其进行多路复用。这似乎是 Go 的方式。
请注意,如果您中的一个接受者失败,则您无法关闭接受通道,因为另一个接受者在写入时会感到恐慌。
我的(更完整的)示例:
newConns := make(chan net.Conn)
// For every listener spawn the following routine
go func(l net.Listener) {
for {
c, err := l.Accept()
if err != nil {
// handle error (and then for example indicate acceptor is down)
newConns <- nil
return
}
newConns <- c
}
}(listener)
for {
select {
case c := <-newConns:
// new connection or nil if acceptor is down, in which case we should
// do something (respawn, stop when everyone is down or just explode)
case <-time.After(time.Minute):
// timeout branch, no connection for a minute
}
}
- 1 回答
- 0 关注
- 178 浏览
添加回答
举报