Go 並發與通道混亂
問題
使用者正在嘗試理解Go 並發通道使用以下程式碼片段:
<code class="go">package main import "fmt" func display(msg string, c chan bool) { fmt.Println("display first message:", msg) c <- true } func sum(c chan bool) { sum := 0 for i := 0; i < 10000000000; i++ { sum++ } fmt.Println(sum) c <- true } func main() { c := make(chan bool) go display("hello", c) go sum(c) <-c }</code>
預期輸出僅為“顯示第一則訊息:你好”,因為主函數一旦從通道接收到資料就應該退出。然而,實際產出還包括 100 億個數字的總和。
答案
程式碼中的主要問題是調度器可以在兩個 goroutine 之間自由選擇(顯示和求和)未被阻止。雖然程式設計師期望顯示首先完成並在求和完成之前將資料發送到通道,但由於調度程序的不確定性,這種情況可能不會發生。
在一個可能的執行場景中:
為了解決這個問題並確保只列印「display first message: hello」訊息,一種方法是使用結果通道接收來自 display 的訊息並立即終止程式。修改後的 main 函數為:
<code class="go">func main() { result := make(chan string) go display("hello", result) fmt.Println(<-result) }</code>
以上是為什麼我的 Go 代碼會列印 100 億個數字的總和,而不是僅僅「顯示第一則訊息:你好」?的詳細內容。更多資訊請關注PHP中文網其他相關文章!