2 回答

TA貢獻(xiàn)1864條經(jīng)驗(yàn) 獲得超2個(gè)贊
簡(jiǎn)短的回答:
對(duì)于任何通道(緩沖或不緩沖),如果沒有任何內(nèi)容寫入通道,則通道讀取塊。
對(duì)于非緩沖通道,如果沒有人在聽,通道寫入將阻塞。
這是錯(cuò)誤通道的常用技術(shù)(因?yàn)橹挥幸粋€(gè)項(xiàng)目會(huì)寫入通道),使其成為大小為 1 的緩沖通道。它確保寫入不會(huì)阻塞 - 并且 writer goroutine 可以繼續(xù)其方式和返回。
因此,服務(wù)不依賴從錯(cuò)誤通道讀取的客戶端調(diào)用者來執(zhí)行其清理。
注意:要回收一個(gè)通道重新 GC,它只需要超出范圍 - 它不需要完全耗盡。也不需要關(guān)閉。一旦它從兩端超出范圍,它將被 GC'ed。

TA貢獻(xiàn)1111條經(jīng)驗(yàn) 獲得超0個(gè)贊
如果您參考 的代碼ListenAndServe(),您會(huì)注意到以下關(guān)于其工作原理的注釋。從那里引用本身:
// ListenAndServe 總是返回一個(gè)非零錯(cuò)誤。在 Shutdown 或 Close 之后,
// 返回的錯(cuò)誤是 ErrServerClosed。
還,
// 當(dāng)調(diào)用 Shutdown 時(shí),Serve、ListenAndServe 和
// ListenAndServeTLS 立即返回 ErrServerClosed。確保
// 程序沒有退出,而是等待 Shutdown 返回。
Shutdown考慮到您正在優(yōu)雅地處理服務(wù)器的關(guān)閉并且不讓 goroutine 在優(yōu)雅關(guān)閉之前退出,您的 select 塊正在等待(錯(cuò)誤)。
在func (srv *Server) Close() (例如,大多數(shù)使用defer srv.Close(),對(duì)嗎?)的情況下:
// Close 立即關(guān)閉所有活動(dòng)的 net.Listener 和任何
// 處于 StateNew、StateActive 或 StateIdle 狀態(tài)的連接。為一個(gè)
// 關(guān)閉返回關(guān)閉服務(wù)器的
// 底層監(jiān)聽器返回的任何錯(cuò)誤。
// 優(yōu)雅關(guān)機(jī),使用 Shutdown。
因此,與上述相同的解釋是使用 select 塊。
現(xiàn)在,讓我們將通道分類為buffered和unbuffered,如果我們確實(shí)關(guān)心信號(hào)傳遞的保證(與通道的通信),那么無緩沖的可以確保它。然而,如果在您的情況下緩沖通道(大小 = 1),那么它可以確保交付但可能會(huì)延遲。
讓我們?cè)敿?xì)說明unbuffered channels:
A send operation on an unbuffered channel blocks the sending goroutine until another
goroutine executes a corresponding receive on that same channel, at which point the value
is transmitted and both goroutines may continue
Conversely, if received on the channel earlier (<-chan) than send operation, then the
receiving goroutine is blocked until the corresponding send operation occurs on the
same channel on another goroutine.
上述無緩沖通道的點(diǎn)表示同步性質(zhì)。
記住,func main()也是一個(gè)goroutine。
讓我們?cè)敿?xì)說明buffered channels:
A send operation on a buffered channel pushes an element at the back of the queue,
and a receive operation pops an element from the front of the queue.
1. If the channel is full, the send operation blocks its goroutine until space is made available by another goroutine's receive.
2. If the channel is empty, a receive operation blocks until a value is sent by another goroutine.
因此,在您的情況下,通道的大小為 1。另一個(gè)發(fā)送者 goroutine 可以以非阻塞方式發(fā)送,因?yàn)榱硪粋€(gè) goroutine 的接收者通道在收到后立即將其出列。但是,如果你還記得,我提到了大小為 1的通道的延遲交付,因?yàn)槲覀儾恢澜邮掌魍ǖ?goroutine 返回需要多少時(shí)間。
因此,使用阻塞發(fā)送者 goroutine select block。從引用代碼的文檔中,您可以看到
// 確保程序不會(huì)退出,而是等待 Shutdown 返回。
另外,為了更清楚,您可以參考:通道 的行為作者非常清楚地解釋了它。
- 2 回答
- 0 關(guān)注
- 147 瀏覽
添加回答
舉報(bào)