[英]Getting value from Go channel
我有一個例程,該例程正在偵聽TCP連接並將其通過通道發送回主循環。 我在例行程序中執行此操作的原因是使此偵聽無阻塞並能夠同時處理活動連接。
我已經使用帶有空默認情況的select語句實現了此操作,如下所示:
go pollTcpConnections(listener, rawConnections)
for {
// Check for new connections (non-blocking)
select {
case tcpConn := <-rawConnections:
currentCon := NewClientConnection()
pendingConnections.PushBack(currentCon)
fmt.Println(currentCon)
go currentCon.Routine(tcpConn)
default:
}
// ... handle active connections
}
這是我的pollTcpConnections例程:
func pollTcpConnections(listener net.Listener, rawConnections chan net.Conn) {
for {
conn, err := listener.Accept() // this blocks, afaik
if(err != nil) {
checkError(err)
}
fmt.Println("New connection")
rawConnections<-conn
}
}
問題是我從沒有收到這些聯系。 如果我以阻止方式進行操作,如下所示:
for {
tcpConn := <-rawConnections
// ...
}
我收到了連接,但是阻塞了...我也嘗試過緩沖通道,但是發生了同樣的事情。 我在這里想念什么?
很難說出為什么您看不到基於現有代碼的任何連接。 示例的一個問題是,在select
語句中有一個空的default
情況,然后我們看不到此for
循環中正在發生什么。 按照您編寫它的方式,該循環可能永遠不會交給調度程序。 您基本上是在說“從渠道中得到東西。沒有東西嗎?好了,重新開始。從渠道中得到東西!”,但是您實際上從未等待。 當您執行一些阻止您的goroutine的操作時,該goroutine將產生給調度程序。 因此,當您以常規方式進行通道讀取時,如果沒有要讀取的值,則該goroutine將被阻止讀取。 由於已被阻塞,因此它也屈服於調度程序,以允許其他goroutine在底層線程上繼續執行。 我敢肯定,這就是為什么default
值為空的select
會中斷的原因。 您正在使該goroutine在for
循環中無限循環,而不會屈服於調度程序。
尚不清楚pendingConnections
的作用是什么,還是根本不需要它。
從該行為無法判斷的另一件事是您的checkError
函數的作用。 例如,它不會繼續到for
循環或bail的頂部。
無論如何,這看起來比需要的要復雜。 只需具有一個將新連接作為一個參數的函數,然后在連接時在新的goroutine中啟動它即可。 我總是這樣寫:
func handleConnection(c net.Conn) {
// do something with your connection here.
}
for {
// Wait for a connection.
conn, err := l.Accept()
if err != nil {
// do something with your error. You probably want to break or return here.
break
}
// handle each connection in a new goroutine
go handleConnection(conn)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.