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

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

Golang緩沖通道在發送之前就已接收數據

Golang緩沖通道在發送之前就已接收數據

Go
肥皂起泡泡 2021-04-09 17:14:53
我剛接觸golang。今天測試通道在Golang中的工作方式時,我感到非常困惑。根據教程:僅當緩沖區已滿時才發送到緩沖的通道塊。當緩沖區為空時接收塊。我的測試程序如下所示:package mainimport "fmt"func main() {    ch := make(chan int, 2)    go func(ch chan int) int {        for i := 0; i < 10; i++ {            fmt.Println("goroutine: GET ", <-ch)        }        return 1    }(ch)    for j := 0; j < 10; j++ {        ch <- j        fmt.Println("PUT into channel", j)    }}我得到這樣的輸出:PUT into channel 0PUT into channel 1goroutine: GET  0goroutine: GET  1goroutine: GET  2PUT into channel 2PUT into channel 3PUT into channel 4PUT into channel 5goroutine: GET  3goroutine: GET  4goroutine: GET  5goroutine: GET  6PUT into channel 6PUT into channel 7PUT into channel 8PUT into channel 9請注意,編號2是從通道中取出的,甚至沒有放入通道中。為什么會這樣?
查看完整描述

1 回答

?
蝴蝶刀刀

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

沒有。將其放在通道上之后Println("PUT into channel")會發生您的情況,這意味著在執行該print語句之前,有機會從通道中讀取它。

示例輸出中的實際執行順序類似于以下內容:

  1. 編寫器例程寫入2通道。

  2. 讀取器例程2從通道接收。

  3. 讀者日常印刷品goroutine: GET  2。

  4. 作家的日常打印 PUT into channel 2

您對通道的讀取和寫入以預期的順序進行,只是您的打印語句使它看起來不正常。

如果您將作者的操作順序更改為:

    fmt.Println("PUT into channel", j)
    ch <- j

您可能會看到輸出更接近您的期望。但是,它不一定完全代表操作順序,因為:

  1. 執行是并發的,但對stdout的寫入是同步的

  2. 每個函數調用和通道發送/接收都為調度程序提供了切換的機會,因此即使使用進行運行GOMAXPROCS=1,它也可以在打印和通道操作(在讀取器或寫入器中)之間切換goroutines。

TL; DR:在記錄并發操作時,不要過多地閱讀日志消息的順序。


查看完整回答
反對 回復 2021-04-19
  • 1 回答
  • 0 關注
  • 273 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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