理解 Golang 中的通道輸出順序
在 Golang 中,無緩衝通道在 goroutine 之間提供了可靠的通訊機制。然而,它們的輸出順序有時可能會令人困惑。考慮以下程式碼:
func main() { messages := make(chan string) go func() { messages <- "hello" }() go func() { messages <- "ping" }() msg := <-messages msg2 := <-messages fmt.Println(msg) fmt.Println(msg2) }
運行此程式碼時,它總是會列印“ping”,然後列印“hello”。這似乎違反直覺,因為人們可能期望輸出與創建 Goroutine 的順序相符。
要理解為什麼會發生這種情況,重要的是要記住通道是通訊管道,而 Goroutine 代表並行任務。即使 Goroutine 是按照特定的順序創建的,它們的執行順序也無法保證。
在這種情況下,排程器可能會將發送「ping」的 Goroutine 安排在發送「hello」的 Goroutine 之前。當第一個接收者(即 msg :=
收到第一則訊息後,程式將繼續執行直到第二個接收器 (msg2 :=
因此,輸出順序由寫入通道的 goroutine 的執行順序決定,而不是它們的建立順序或從通道讀取訊息的順序。要驗證這一點,可以按照提供的答案中的建議向Goroutine 添加一條Println 語句:
... func() { messages <- "hello"; fmt.Println("Hello sent") }() func() { messages <- "ping"; fmt.Println("Ping sent") }() ...
這將輸出:
Hello sent Ping sent ping hello
這確認訊息已發送並以相同的順序列印。
以上是為什麼 Golang 的無緩衝通道輸出順序看起來違反直覺?的詳細內容。更多資訊請關注PHP中文網其他相關文章!