首頁 > 後端開發 > Golang > 主體

為什麼通道不採用最後聲明的值?

WBOY
發布: 2024-02-09 09:15:11
轉載
1130 人瀏覽過

為什麼通道不採用最後聲明的值?

在PHP中,通道(channel)是一種用於並發程式設計的重要概念。它允許不同的協程(goroutine)之間進行通訊和同步操作。然而,有一個常見的疑問是:「為什麼通道不採用最後聲明的值?」這個問題涉及通道的設計原則和使用方式。通道在接收操作時,會阻塞等待發送方發送資料。當發送方發送完資料後,接收方才能繼續執行。因此,通道的值是在發送方發送資料時確定的,而不是在接收方接收資料時確定的。這是為了確保通訊的可靠性和一致性。所以,即使最後聲明的值在接收方接收時已經改變,通道仍然會採用發送時的值。這樣做可以避免數據的不一致性和混亂,確保溝通的可靠性和準確性。

問題內容

我正在嘗試了解頻道。在這段程式碼中,我聲明了從 1 到 10 的值。最終聲明的值為 10,但是當我列印它時,它總是會傳回 before(8) 之前兩個宣告的值。如果有人能解釋一下,我會很高興。

func main() {
    channel := make(chan int, 3)
    isOver := make(chan bool)

    go func() {
        for val := range channel {
            fmt.Println(val)
        }
        isOver <- true
    }()

    channel <- 1
    channel <- 2
    channel <- 3
    channel <- 4
    channel <- 5
    channel <- 6
    channel <- 7
    channel <- 8
    channel <- 9
    channel <- 10
    close(channel)

    fmt.Println("Channel Value is: ", <-channel)

    <-isOver

}
登入後複製

當我將聲明更改為 8 時,它會傳回之前兩個聲明的值,即 6。

解決方法

因為你為通道設定了3個緩衝區大小!

注意:您的範例在不同的作業系統中具有不同的輸出(例如我得到 Channel 值為:0

設定時間。在程式碼中休眠看看會發生什麼事。在您的程式碼中:

<code>func main() {
    channel := make(chan int)
    isOver := make(chan bool)

    go func() {
        for val := range channel {
            fmt.Println(val)
            // sleep 1 second
            time.Sleep(1 * time.Second)
        }
        isOver <- true
    }()

    channel <- 1
    channel <- 2
    channel <- 3
    channel <- 4
    channel <- 5
    channel <- 6
    channel <- 7
    channel <- 8
    channel <- 9
    channel <- 10
    close(channel)

    fmt.Println("Channel Value is: ", <-channel)
    <-isOver
}

</code>
登入後複製

輸出為:

1
2
3
4
5
6
7
Channel Value is:  8
9
10
登入後複製

注意:了解程式碼中發生的情況的更好方法是逐步追蹤程式碼。

發生了什麼事? 看到這個痕跡:

1 // print 1 and sleep 1s
2,3,4 // stop for get values

3,4 // print 2 and sleep 1
3,4,5 // stop for get value

4,5 // print 3 and sleep 1
4,5,6 // stop for get value

5,6 // print 4 and sleep 1
5,6,7 // stop for get value

6,7 // print 5 and sleep 1
6,7,8 // stop for get value

7,8 // print 6 and sleep 1
7,8,9 // stop for get value

8,9 // print 7 and sleep 1
8,9,10 // stop for get value
// close channel
// in this line get value : fmt.Println("Channel Value is: ", <-channel)

9,10 // before get value
10 // get 9 and sleep 1
// get 10 and sleep 1

// isdone send signal true
登入後複製

在追蹤程式碼中,當通道取得樹值 8,9,10 時,通道關閉,在步驟 2 中發生了事情:

1 - 如果 goroutine 快速取得所有值(通道值為:0)
2 - 如果 goroutine 繁忙(通道值為:7 或 8 或 9 或 10)

有關詳細信息,請參閱此問題:何時使用緩衝通道 並查看此網站以更好地理解:連結

以上是為什麼通道不採用最後聲明的值?的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:stackoverflow.com
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
最新問題
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!