首頁 > 後端開發 > Golang > 為什麼 Go 的 select 語句需要 fmt.Print() 來終止特定的 Goroutine?

為什麼 Go 的 select 語句需要 fmt.Print() 來終止特定的 Goroutine?

Susan Sarandon
發布: 2024-11-26 05:40:10
原創
872 人瀏覽過

Why Does a Go `select` Statement Need `fmt.Print()` to Terminate in a Specific Goroutine?

帶有select 的goroute 不會在沒有fmt.Print() 的情況下終止

在Go Tour 練習#71 中,帶有select 語句的goroute除非在預設情況下加入fmt.Print() 語句,否則將連續執行。出現此行為的原因是存在預設語句時 select 的操作發生了變化。

如果沒有預設語句,select 會阻塞,直到在任何正在監視的頻道上收到訊息為止。透過新增預設值,只要沒有通道有訊息,select就會執行預設分支。

在原始程式碼中,default語句建立了一個無限迴圈:

for {
    select {
        case todo := <-toDoList:
            ...
        case <-doneCrawling:
            ...
        default:
            if os.Args[1] == "ok" {
                fmt.Print("")
            }
            if crawling == 0 {
                goto END
            }
        }
    }
登入後複製

沒有fmt。預設情況下,調度器無法調度其他goroutine,從而導致死鎖。新增 fmt.Print() 可以讓調度程式繼續其正常功能,從而使 goroutine 能夠完成。

修改程式碼以使用非阻塞 select 可以解決問題:

for {
    select {
        case todo := <-toDoList:
            ...
        case <-doneCrawling:
            ...
    }
    if crawling == 0 {
        break
    }
}
登入後複製

或者,可以透過設定 GOMAXPROCS=2 來使原始程式碼正常運作,這表示排程器過載存在問題。

以上是為什麼 Go 的 select 語句需要 fmt.Print() 來終止特定的 Goroutine?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板