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

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

常規(guī)處理頻道范圍

常規(guī)處理頻道范圍

Go
慕虎7371278 2023-04-24 16:55:29
我在 Golang 工作了很長時間。但是,盡管我知道解決問題的方法,但我仍然面臨這個問題。但是從來沒有想過為什么會這樣。例如,如果我有如下入站和出站通道的管道情況:package mainimport (    "fmt")func main() {    for n := range sq(sq(gen(3, 4))) {        fmt.Println(n)    }    fmt.Println("Process completed")}func gen(nums ...int) <-chan int {    out := make(chan int)    go func() {        for _, n := range nums {            out <- n        }        close(out)    }()    return out}func sq(in <-chan int) <-chan int {    out := make(chan int)    go func() {        for n := range in {            out <- n * n        }        close(out)    }()    return out}它不會給我?guī)斫┚?。但是,如果我刪除出站代碼中的 go 例程,如下所示:func sq(in <-chan int) <-chan int {    out := make(chan int)    for n := range in {        out <- n * n    }    close(out)    return out}我收到死鎖錯誤。為什么在沒有 go routine 的情況下使用 range 循環(huán)通道會導(dǎo)致死鎖。
查看完整描述

4 回答

?
隔江千里

TA貢獻(xiàn)1906條經(jīng)驗 獲得超10個贊

sq這種情況是函數(shù)的輸出通道沒有緩沖造成的。所以sq等待下一個函數(shù)從輸出中讀取,但如果sq不是異步的,它就不會發(fā)生:

package main


import (

? ? "fmt"

? ? "sync"

)


var wg sync.WaitGroup


func main() {

? ? numsCh := gen(3, 4)

? ? sqCh := sq(numsCh) // if there is no sq in body - we are locked here until input channel will be closed

? ? result := sq(sqCh) // but if output channel is not buffered, so `sq` is locked, until next function will read from output channel


? ? for n := range result {

? ? ? ? fmt.Println(n)

? ? }

? ? fmt.Println("Process completed")

}


func gen(nums ...int) <-chan int {

? ? out := make(chan int)

? ? go func() {

? ? ? ? for _, n := range nums {

? ? ? ? ? ? out <- n

? ? ? ? }

? ? ? ? close(out)

? ? }()

? ? return out

}


func sq(in <-chan int) <-chan int {

? ? out := make(chan int, 100)

? ? for n := range in {

? ? ? ? out <- n * n

? ? }

? ? close(out)

? ? return out

}


查看完整回答
反對 回復(fù) 2023-04-24
?
夢里花落0921

TA貢獻(xiàn)1772條經(jīng)驗 獲得超6個贊

你的函數(shù)創(chuàng)建一個通道,寫入它,然后返回它。寫入將阻塞,直到有人可以讀取相應(yīng)的值,但這是不可能的,因為此函數(shù)之外還沒有人擁有通道。


func sq(in <-chan int) <-chan int {

    // Nobody else has this channel yet...

    out := make(chan int)

    for n := range in {

        // ...but this line will block until somebody reads the value...

        out <- n * n

    }

    close(out)

    // ...and nobody else can possibly read it until after this return.

    return out

}

如果將循環(huán)包裝在 goroutine 中,則允許循環(huán)和函數(shù)sq繼續(xù);即使循環(huán)阻塞,return out語句仍然可以繼續(xù),最終您將能夠?qū)㈤喿x器連接到通道。


(在 goroutines 之外的通道上循環(huán)本質(zhì)上沒有什么壞處;你的main函數(shù)無害且正確地完成了它。)


查看完整回答
反對 回復(fù) 2023-04-24
?
ITMISS

TA貢獻(xiàn)1871條經(jīng)驗 獲得超8個贊

代碼有點復(fù)雜,我們簡化一下


下面的第一個 eq,沒有死鎖


func main() {

    send := make(chan int)

    receive := make(chan int)

    go func() {

        send<-3

        send<-4

        close(send)

    }()

    go func() {

        receive<- <-send

        receive<- <-send

        close(receive)

    }()

    for v := range receive{

        fmt.Println(v)


    }

}

下面的第二個 eq,刪除“go”有死鎖


func main() {

    send := make(chan int)

    receive := make(chan int)

    go func() {

        send<-3

        send<-4

        close(send)

    }()

    receive<- <-send

    receive<- <-send

    close(receive)

    for v := range receive{

        fmt.Println(v)


    }

}

讓我們再次簡化第二個代碼


func main() {

    ch := make(chan int)

    ch <- 3

    ch <- 4

    close(ch)

    for v := range ch{

        fmt.Println(v)


    }

}

死鎖的原因是主協(xié)程中沒有等待的緩沖通道。


兩種解決方案


// add more cap then "channel<-" time

func main() {

    ch := make(chan int,2)

    ch <- 3

    ch <- 4

    close(ch)

    for v := range ch{

        fmt.Println(v)


    }

}


//async "<-channel"

func main() {

    ch := make(chan int)

    go func() {

        for v := range ch {

            fmt.Println(v)

        }

    }()

    ch <- 3

    ch <- 4

    close(ch)

}


查看完整回答
反對 回復(fù) 2023-04-24
?
撒科打諢

TA貢獻(xiàn)1934條經(jīng)驗 獲得超2個贊

死鎖的原因是因為 main 正在等待 returnsq和 finish,而 thesq正在等待有人讀取 chan 然后它可以繼續(xù)。


我通過刪除 sq 調(diào)用層來簡化您的代碼,并將一個句子分成 2 個:


func main() {

    result := sq(gen(3, 4)) // <-- block here, because sq doesn't return

    for n := range result { 

        fmt.Println(n)

    }

    fmt.Println("Process completed")

}


func gen(nums ...int) <-chan int {

    out := make(chan int)

    go func() {

        for _, n := range nums {

            out <- n

        }

        close(out)

    }()

    return out

}


func sq(in <-chan int) <-chan int {

    out := make(chan int)

    for n := range in {

        out <- n * n   // <-- block here, because no one is reading from the chan

    }

    close(out)

    return out

}

在sq方法中,如果把代碼放入goroutine,willsq返回,main func不會阻塞,消費結(jié)果隊列,willgoroutine繼續(xù),就沒有阻塞了。


func main() {

    result := sq(gen(3, 4)) // will not blcok here, because the sq just start a goroutine and return

    for n := range result {

        fmt.Println(n)

    }

    fmt.Println("Process completed")

}


func gen(nums ...int) <-chan int {

    out := make(chan int)

    go func() {

        for _, n := range nums {

            out <- n

        }

        close(out)

    }()

    return out

}


func sq(in <-chan int) <-chan int {

    out := make(chan int)

    go func() {

        for n := range in {

            out <- n * n // will not block here, because main will continue and read the out chan

        }

        close(out)

    }()

    return out

}


查看完整回答
反對 回復(fù) 2023-04-24
  • 4 回答
  • 0 關(guān)注
  • 175 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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