亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

Go 通道和延遲

Go 通道和延遲

Go
慕的地6264312 2023-06-05 18:27:37
我只是在我的 Ubuntu 64 位環境中試驗 Go 通道,并對以下程序產生的輸出感到困惑。我得到輸出:0 1 2 3 退出當我取消注釋兩個注釋行時的輸出:0 1 2 3 4 Exit請解釋行為。TIA。package mainimport ("fmt"    //"time")func main() {    ch := make(chan int)    done := make(chan bool)    go func() {        for i := 0; i < 5; i++ {            ch <- i        }                //time.Sleep(1 * time.Second)        done <- false    }()    go func() {        for {            select {            case message := <-ch:                fmt.Println(message)            case <-done:                return            }        }    }()    <-done    fmt.Println("Exit")}
查看完整描述

3 回答

?
汪汪一只貓

TA貢獻1898條經驗 獲得超8個贊

您的主線程正在等待done,然后退出。同時,您的第一個 go 函數將 5 個值通過管道傳輸到ch,然后發送到done。

then中的值done從主線程中讀取,并且恰好發生在第二個 go 函數從中讀取最后一個值之前ch。當它這樣做時,它退出程序。

請注意,如果您的第二個線程確實碰巧同時讀取了chdone,那么您的程序將死鎖,因為主線程永遠不會接收 ondone并且所有正在運行的 go 線程將被阻塞以等待在通道上接收。


查看完整回答
反對 回復 2023-06-05
?
明月笑刀無情

TA貢獻1828條經驗 獲得超4個贊

您不是在等待兩個 goroutine,而是只將一個值發送done到 2 個接收者,如果第二個接收者恰好是main.

使用 aWaitGroup可以簡化代碼,并允許您輕松等待所需數量的 goroutine。https://play.golang.org/p/MWknv_9AFKp

ch := make(chan int)

var wg sync.WaitGroup


wg.Add(1)

go func() {

    defer wg.Done()

    defer close(ch)

    for i := 0; i < 5; i++ {

        ch <- i

    }

}()


wg.Add(1)

go func() {

    defer wg.Done()

    for message := range ch {

        fmt.Println(message)

    }


}()


wg.Wait()

fmt.Println("Exit")


查看完整回答
反對 回復 2023-06-05
?
DIEA

TA貢獻1820條經驗 獲得超2個贊

您有兩個go并行運行的例程。一個向通道中插入 5 個數字,然后向主線程發出退出信號,另一個從通道中讀取數字。

請注意,一旦負責將數字排入通道的 go 例程完成,它就會向主線程發出退出信號,而不管讀取數字的 go 例程是否完成。因此,您可能會遇到這樣一種情況,即入隊例程在出隊完成之前完成,并且主線程退出。

通過添加睡眠,您可以使入隊例程的壽命更長一些,并讓出隊例程有機會在入隊例程向主線程發出退出信號之前讀取和打印所有數字。

要解決這個問題,您可以只在主線程中運行出隊代碼。在這種情況下,無需在 go 例程中運行它。


查看完整回答
反對 回復 2023-06-05
  • 3 回答
  • 0 關注
  • 164 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號