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

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

Go Channel 寫入超出其容量的數據

Go Channel 寫入超出其容量的數據

Go
絕地無雙 2022-10-24 09:59:35
package mainimport (    "fmt")func write(ch chan int) {    for i := 0; i < 5; i++ {        fmt.Println("avaliable", i)        ch <- i        fmt.Println("successfully wrote", i, "to ch")    }    close(ch)}func main() {    ch := make(chan int)    go write(ch)    for v := range ch {        fmt.Println("read value", v, "from ch")    }}輸出avaliable 0successfully wrote 0 to chavaliable 1read value 0 from chread value 1 from chsuccessfully wrote 1 to chavaliable 2successfully wrote 2 to chavaliable 3read value 2 from chread value 3 from chsuccessfully wrote 3 to chavaliable 4successfully wrote 4 to chread value 4 from ch由于這是一個無緩沖的通道,它應該在數據寫入它時立即阻塞,直到另一個 goroutine 從同一通道讀取。但它接受的數據超出了它的能力。預期行為package mainimport (    "fmt"    "time")func write(ch chan int) {    for i := 0; i < 5; i++ {        fmt.Println("avaliable", i)        ch <- i        fmt.Println("successfully wrote", i, "to ch")    }    close(ch)}func main() {    ch := make(chan int)    go write(ch)    time.Sleep(time.Second)    for v := range ch {        fmt.Println("read value", v, "from ch")        time.Sleep(time.Second)    }}輸出avaliable 0read value 0 from chsuccessfully wrote 0 to chavaliable 1read value 1 from chsuccessfully wrote 1 to chavaliable 2read value 2 from chsuccessfully wrote 2 to chavaliable 3read value 3 from chsuccessfully wrote 3 to chavaliable 4read value 4 from chsuccessfully wrote 4 to ch如果在整個代碼中放置了一些計時器,以便主 goroutine 在每次迭代之前被阻塞,它就會按預期工作。
查看完整描述

2 回答

?
HUX布斯

TA貢獻1876條經驗 獲得超6個贊

您無法從輸出中推斷出任何內容,因為“讀取值”和“成功寫入”Printfs 執行之間沒有順序保證。(在通道發送之前發生的“可用”Printf 和在相應通道接收之后發生的“讀取值”Printf 之間存在一個,您可以看到輸出中永遠不會違反該順序)。

通道沒有緩沖任何東西,因為它沒有緩沖;只是通道發送完成后,兩個不同的 goroutine 以不確定的順序運行。有時發送方先走并打印“成功寫入”消息,有時接收方先走并打印“讀取值”消息。沒有一個“領先”超過一個值,因為它們仍然在通道發送上完全同步;他們只是在比賽之后立即打印他們的狀態消息。

當您將 Sleep 調用添加到 main 時,它恰好使運行的 goroutinewrite在等待發送下一個值時總是被阻塞,而正在運行的 goroutinemain在調用時阻塞Sleep。當定時器超時時,主協程被喚醒,并立即發現它在通道上等待它的東西,抓住它,然后重新進入睡眠狀態,然后write協程被喚醒。通過放慢速度,您已經讓調度程序以一致的順序運行事物(盡管這仍然部分是運氣問題);沒有睡眠,一切都盡可能快地運行,結果顯然是隨機的。


查看完整回答
反對 回復 2022-10-24
?
精慕HU

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

如果是這樣的話,“睡眠”版本的輸出會更加混亂。

即使它們在某個點同步,您也不能期望兩個獨立線程的一致輸出。


查看完整回答
反對 回復 2022-10-24
  • 2 回答
  • 0 關注
  • 228 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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