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 關注
- 201 瀏覽
添加回答
舉報