首頁 >後端開發 >Golang >為什麼帶 Goroutine 的 Go Select 語句會掛起,除非加入 Print 語句?

為什麼帶 Goroutine 的 Go Select 語句會掛起,除非加入 Print 語句?

Linda Hamilton
Linda Hamilton原創
2024-11-26 22:46:11431瀏覽

Why Does a Go Select Statement with a Goroutine Hang Unless a Print Statement is Added?

有Select 的Goroutine 不會停止,除非加上列印語句

在Go Tour 練習#71 中,使用不帶預設值的select語句可能會導致無限循環,從而阻止goroutine 退出。使用 nogood 參數執行 71_hang.go 時會遇到此問題,但使用 ok 參數則不會。

兩個場景之間的差異在於預設有額外的 fmt.Print("") 語句select 語句的情況。預設情況下,選擇區塊直到其中一個通道有訊息要接收。然而,在預設情況下,即使沒有通道有訊息可用,select 也會執行預設語句。

在原始程式碼中,沒有 fmt.Print("") 語句,select 語句輸入了一個無限循環,因為沒有可用訊息的通道,並且預設情況下不執行任何操作來允許 goroutine 進行調度。添加 fmt.Print("") 語句允許調度程序調度其他 goroutine 並打破無限循環。

或者,可以修改程式碼以非阻塞方式使用 select,從而允許其他 goroutine才能正常運作。這可以透過刪除預設語句並使用單獨的 if 語句來檢查抓取計數器是否已達到零來實現,如下面修改後的程式碼所示:

for {
    select {
        case todo := <-toDoList:
            if todo.depth > 0 && !visited[todo.url] {
                crawling++
                visited[todo.url] = true
                go crawl(todo, fetcher, toDoList, doneCrawling)
            }
        case <-doneCrawling:
            crawling--
    }
    if crawling == 0 {
        break
    }
}

以上是為什麼帶 Goroutine 的 Go Select 語句會掛起,除非加入 Print 語句?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn