[英]Go trouble with buffered and unbuffered channels
我對 Go 中緩沖通道和非緩沖通道之間的區別有點困惑。 例如,下面的代碼執行良好:
package main
import "fmt"
func main() {
messages := make(chan string)
go func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
另一方面,當我將"ping"
傳遞給常規 function 中的消息時,會出現死鎖。
package main
import "fmt"
func main() {
messages := make(chan string)
func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
最后,當我使用緩沖通道時,這是固定的,就像這樣
package main
import "fmt"
func main() {
messages := make(chan string, 1)
func() { messages <- "ping" }()
msg := <-messages
fmt.Println(msg)
}
我很困惑為什么第二個案例失敗了。 Go By Example 說
默認情況下,通道是無緩沖的,這意味着如果有相應的接收 (<- chan) 准備好接收發送的值,它們將只接受發送 (chan <-)。 緩沖通道接受有限數量的值,而這些值沒有相應的接收器。
在這三種情況下,不是msg
messages
器嗎?
如果未讀取無緩沖通道,則它們會阻塞。 緩沖通道在達到容量之前不會阻塞。
您的第一個示例實際上啟動了一個單獨的 go 例程,該例程執行 function 嘗試將“ping”寫入消息通道。 它將阻塞,直到從消息通道讀取的語句執行。 由於 function 位於單獨的 goroutine 上,因此從消息通道讀取的語句能夠被命中。
您的第二個示例聲明並調用 function 嘗試寫入消息通道,但該通道永遠不會准備好寫入,因為您正在同一個主執行線程上執行。 從消息通道讀取的語句永遠不會命中,因為您在寫入通道時被阻止。
第三個例子,通道被緩沖並且可以被寫入,因為它可以在阻塞之前接受 1 個值。
在第一個示例中,嵌套的 function 從另一個 goroutine 調用。 function 開始運行並阻塞等待寫入通道。 主 goroutine 也運行,並從通道讀取,釋放第二個 goroutine 中的塊。
在第二個例子中,嵌套的 function 被 main 調用,main 等待它返回。 由於通道沒有緩沖,寫操作阻塞,這意味着主協程被阻塞,沒有其他協程,所以死鎖。
在第三個示例中,通道被緩沖,因此第一次寫入不會阻塞。
您可能已經瀏覽了那里的一個關鍵詞:“如果有相應的接收 (<-chan)准備好接收發送的值”。
在您的第一個示例中,接收器與發送器同時運行,因此當發送器發送時,接收器此時已准備好接收。 在第二個示例中,它們沒有同時運行,因此當發送方發送時,沒有准備好接收(因為接收操作在匿名 function 返回之前不會運行),並且發送阻塞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.