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

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

為什么我在等待后關(guān)閉頻道時(shí),所有 Goroutine 都處于睡眠狀態(tài)?

為什么我在等待后關(guān)閉頻道時(shí),所有 Goroutine 都處于睡眠狀態(tài)?

Go
明月笑刀無(wú)情 2022-09-05 15:46:59
代碼如下:func makeData() map[string][]Data {    m := make(map[string][]Data)    s := "abcdefghijklmno"    for i, c := range s {        data := []Data{            {value: "hey_" + string(c), id: i * i},            {value: "hello_" + string(c) + string(c), id: i + i},            {value: "bye_" + string(c), id: i + 1},        }        m[strconv.Itoa(i)] = data    }    return m}func process(key string, value []Data) (*Result, error) {    if key == "hey_a" {        return nil, errors.New("error")    }    res := Result{data: Data{value: "hi", id: 0}, id: 1}    return &res, nil}func main() {    runtime.GOMAXPROCS(runtime.NumCPU())    m := makeData()    errg := new(errgroup.Group)    mapChan := make(chan StringAndData)    sliceChan := make(chan *Result)    for key, value := range m {        key := key        value := value        errg.Go(func() error {            return func(key string, value []Data) error {                res, err := process(key, value)                if err != nil {                    return err                }                if res == nil {                    return nil                }                if res.data.id == 1 {                    mapChan <- StringAndData{                        str:  key,                        data: res.data,                    }                    return nil                }                sliceChan <- res                return nil            }(key, value)        })    }    if err := errg.Wait(); err != nil {        fmt.Println("error")    } else {        fmt.Println("success")    }    close(mapChan)    close(sliceChan)    for ac := range mapChan {        fmt.Println(ac.str)    }}type Data struct {    value string    id    int}type Result struct {    data Data    id   int}type StringAndData struct {    str  string    data Data}操場(chǎng)我得到了,但我正在關(guān)閉頻道之后,我無(wú)法理解原因。fatal error: all goroutines are asleep - deadlock!errg.Wait()我正在嘗試打印使用 關(guān)閉通道后從通道獲得的值。range我是 Go 的渠道和并發(fā)新手,非常感謝任何幫助!編輯添加了游樂(lè)場(chǎng)鏈接中的所有代碼
查看完整描述

1 回答

?
蝴蝶刀刀

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

查看代碼,有兩件事可能會(huì)導(dǎo)致死鎖:

  • errg.Wait()阻止主 goroutine 的執(zhí)行,直到所有初始化的 goroutine 都完成。但是,在嘗試寫(xiě)入 時(shí),每個(gè) goroutine 都會(huì)被阻止,因?yàn)槟肋h(yuǎn)無(wú)法從中讀取(因?yàn)樗挥?)。mapChanerrg.Wait()

  • 你從來(lái)沒(méi)有讀過(guò),所以這是一個(gè)潛在的死鎖。sliceChan

以下是修改后的 Playground 代碼的鏈接,但大多數(shù)更改都在函數(shù)中。main

func main() {

    runtime.GOMAXPROCS(runtime.NumCPU())

    m := makeData()

    errg := new(errgroup.Group)


    mapChan := make(chan StringAndData)

    sliceChan := make(chan *Result)

    mapDone := make(chan bool)

    sliceDone := make(chan bool)


    go func(){

        for ac := range mapChan {

            fmt.Println(ac.str)

        }

        mapDone <- true

    }()

    go func(){

        for ac := range sliceChan {

            fmt.Println(ac)

        }

        sliceDone <- true

    }()


    for key, value := range m {

        key := key

        value := value


        errg.Go(func() error {

            return func(key string, value []Data) error {

                res, err := process(key, value)

                if err != nil {

                    return err

                }

                if res == nil {

                    return nil

                }


                if res.data.id == 1 {

                    mapChan <- StringAndData{

                        str:  key,

                        data: res.data,

                    }

                    return nil

                }


                sliceChan <- res

                return nil


            }(key, value)

        })

    }


    if err := errg.Wait(); err != nil {

        fmt.Println("error")

    } else {

        fmt.Println("success")

    }


    close(mapChan)

    close(sliceChan)

    <-mapDone

    <-sliceDone

    fmt.Println("finished")


}

基本上,我更改了從中讀取值和通道的方式。這是在單獨(dú)的goroutines中完成的,因此不會(huì)阻止從這些通道讀取。mapChansliceChan


添加 和 通道只是為了確保在 goroutine 完成之前讀取所有數(shù)據(jù)。mapDonesliceDonemain


查看完整回答
反對(duì) 回復(fù) 2022-09-05
  • 1 回答
  • 0 關(guān)注
  • 125 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號(hào)

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