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

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

Go Channels 行為似乎不一致

Go Channels 行為似乎不一致

Go
開心每一天1111 2021-09-13 14:38:18
我發現無緩沖通道的工作方式不一致 - 這要么是 Go 中的不一致,要么是我對 Go 的理解......這是一個帶有輸出的簡單示例?!安灰恢隆迸c“制造渠道”線有關。package mainimport (    "fmt"    )func send(sendto chan string) {    fmt.Println("send 1")    sendto <- "Hello"    fmt.Println("send 2")    sendto <- "World"    fmt.Println("send 3")    sendto <- ""    fmt.Println("send() exit")}func main() {    //hole := make(chan string)    //hole := make(chan string, 0)    hole := make(chan string, 1)    go send(hole)    fmt.Println("main loop")    carryon := true    for carryon {        msg := <- hole        if msg == "" {            carryon = false        } else {            fmt.Println(" recd ", msg)        }    }}當我按上述方式運行時,輸出符合預期(對于緩沖區大小為 2 的情況也符合預期)。即通道有一個緩沖區為 1,它保存一個值 - 在下一次嘗試寫入時,有一個上下文切換到 main 以允許它使用第一個值。main loopsend 1send 2 recd  Hellosend 3 recd  Worldsend() exit當我將 make 通道行更改為:hole := make(chan string, 0)輸出是:main loopsend 1send 2 recd  Hello recd  Worldsend 3send() exit我原以為send 2和 是recd Hello相反的......我得到相同的輸出 hole := make(chan string)我檢查了規范,它說容量(以元素數為單位)設置通道中緩沖區的大小。如果容量為零或不存在,則通道沒有緩沖,只有當發送方和接收方都準備好時,通信才能成功。否則,如果緩沖區未滿(發送)或非空(接收),則通道被緩沖并且通信成功而不會阻塞。請有人解釋一下為什么我的期望是錯誤的 - 請善待或者 Go 是否真的錯了謝謝
查看完整描述

3 回答

?
蝴蝶不菲

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

這兩個 goroutine 的時間線顯示了正在發生的事情:


send()                  main()


fmt.Println("send 1")

sendto <- "Hello"       msg := <- hole              // sender and receiver both ready

fmt.Println("send 2")

                        fmt.Println(" recd ", msg)  // msg is "Hello"

sendto <- "World"       msg := <- hole              // sender and receiver both ready

                        fmt.Println(" recd ", msg)  // msg is "World"

fmt.Println("send 3")

sendto <- ""

fmt.Println("send() exit")

send 2之前打印,recd Hello因為 send() 在運行時調度 main() 再次運行之前運行到打印語句。


打印兩條消息的關系之前沒有發生。它們可以按任一順序打印。


查看完整回答
反對 回復 2021-09-13
?
繁星點點滴滴

TA貢獻1803條經驗 獲得超3個贊

大致:發送和接收同時發生。詳細信息在決定此行為的 Go Memory Model 中進行了解釋。并發代碼很復雜...


查看完整回答
反對 回復 2021-09-13
?
holdtom

TA貢獻1805條經驗 獲得超10個贊

只有當發送方和接收方都準備好時,通信才會成功

關鍵是這不需要接收方立即開始處理它收到的消息。特別是在您的情況下,它已準備就緒,因此它無需調用調度程序即可接收該值(無上下文切換)。goroutine 繼續運行,直到它再次嘗試發送,此時接收器還沒有準備好,因此調度程序被調用等。


查看完整回答
反對 回復 2021-09-13
  • 3 回答
  • 0 關注
  • 193 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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