第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

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

如何在 Go Concurrency Patterns fan-in 示例中推理 Go 通道阻塞?

如何在 Go Concurrency Patterns fan-in 示例中推理 Go 通道阻塞?

Go
MMTTMM 2022-10-31 15:33:43
package mainimport (    "fmt"    "math/rand"    "time")func boring(msg string) <-chan string { // Returns receive-only channel of strings.    c := make(chan string)    go func() { // We launch the goroutine from inside the function.        for i := 0; ; i++ {            c <- fmt.Sprintf("%s %d", msg, i)            time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)        }    }()    return c // Return the channel to the caller.}func fanIn(input1, input2 <-chan string) <-chan string {    c := make(chan string)    go func() {        for {            c <- <-input1        }    }()    go func() {        for {            c <- <-input2        }    }()    return c}func main() {    c := fanIn(boring("Joe"), boring("Ann"))    for i := 0; i < 10; i++ {        fmt.Println(<-c)    }    fmt.Println("You're both boring; I'm leaving.")}這是 Rob Pike 關(guān)于Go 并發(fā)模式的演講中的一個示例。我理解扇入模式背后的想法,并且我理解在 main 中打印消息的順序是不確定的:我們只打印 10 條結(jié)果證明已經(jīng)準備好的消息。然而,我不完全理解的是調(diào)用的順序以及什么阻塞了什么。僅使用無緩沖通道,因此根據(jù)文檔,無緩沖通道會阻止發(fā)送方。該boring函數(shù)啟動一個 goroutine,將字符串發(fā)送到c返回的無緩沖通道。如果我理解正確,這個內(nèi)部 goroutine 會啟動但不會阻塞boring。它可以立即將通道返回main給fanIn函數(shù)。但fanIn做幾乎相同的事情:它從輸入通道接收值并將它們發(fā)送到返回的自己的通道。阻塞是如何發(fā)生的?在這種情況下是什么阻止了什么?一個示意性的解釋將是完美的,因為老實說,即使我有一個直觀的理解,我也想了解它背后的確切邏輯。我的直觀理解是,每次發(fā)送都boring阻塞,直到接收到值fanIn,但隨后該值立即發(fā)送到另一個通道,因此它被阻塞,直到接收到值main。粗略地說,這三個功能由于使用了通道而緊密地綁定在一起
查看完整描述

1 回答

?
30秒到達戰(zhàn)場

TA貢獻1828條經(jīng)驗 獲得超6個贊

阻塞是如何發(fā)生的?在這種情況下是什么阻止了什么?

如果另一側(cè)沒有相應(yīng)的接收操作(或者如果通道是nil,則成為沒有接收器的情況),則無緩沖通道上的每個發(fā)送都會阻塞。

考慮到main調(diào)用boringfanIn順序發(fā)生的情況。特別是這一行:

c := fanIn(boring("Joe"), boring("Ann"))

有評估順序:

  1. boring("Joe")

  2. boring("Ann")

  3. fanIn

中的發(fā)送操作并在 中boring("Joe")具有boring("Ann")相應(yīng)的接收操作fanIn,因此它們會阻塞直到fanIn運行。因此boring產(chǎn)生了自己的 goroutine 以確保它在fanIn可以開始接收之前返回通道。

中的發(fā)送操作在 中fanIn具有相應(yīng)的接收操作main,因此它們將阻塞直到fmt.Println(<-c)運行。因此fanIn產(chǎn)生它自己的 goroutine(s) 以確保它在main可以開始接收它之前返回輸出通道。

finallymain的執(zhí)行讓fmt.Println(<-c)一切都開始運轉(zhuǎn)。接收c解除阻塞c <- <-input[1|2]和接收<-input[1|2]解除阻塞c <- fmt.Sprintf("%s %d", msg, i)。

如果去掉 中的接收操作main,main仍然可以繼續(xù)執(zhí)行,程序馬上退出,不會發(fā)生死鎖。


查看完整回答
反對 回復(fù) 2022-10-31
  • 1 回答
  • 0 關(guān)注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動學(xué)習(xí)伙伴

公眾號

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號