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

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

并發(fā)處理程序正在阻塞

并發(fā)處理程序正在阻塞

Go
阿波羅的戰(zhàn)車 2022-10-04 16:20:00
我們發(fā)現(xiàn)一個(gè)工作不正常。在處理程序中,我們將過(guò)濾即將到來(lái)的消息,然后將有效事件傳遞給一個(gè) func 進(jìn)行處理。該功能實(shí)現(xiàn)如下:mqtt.MessageHandlerfunc processEvent(i models.Foo) (string, error) {    var wg sync.WaitGroup    quit := make(chan bool)    errc := make(chan error)    done := make(chan error)    err := func1()    if err != nil {        return err    }    switch strings.ToUpper(i.Status) {    case "OK":        wg.Add(1)        go func() {            defer wg.Done()            err = longTimeTask1()            ch := done            if err != nil {                log.Error("%s", err.Error())                ch = errc            }            select {            case ch <- err:                return            case <-quit:                return            }        }()        wg.Add(1)        go func() {            defer wg.Done()            err = longTimeTask2()            ch := done            if err != nil {                ch = errc            }            select {            case ch <- err:                return            case <-quit:                return            }        }()        result := "processed"        count := 0        for {            select {            case err := <-errc:                close(quit)                log.Info("event: %s, %s", "", err.Error())                return "", err            case <-done:                count++                if count == 4 { // why 4???                    return result, nil                }            }        }        wg.Wait()        if err != nil {            log.Info("event: %s, %s", result, err.Error())            return result, err        }        close(quit)        close(errc)        close(done)        return result, nil    default:        return "", nil    }    return "", nil}我明白了,它正試圖同步和長(zhǎng)時(shí)間任務(wù)2()。但對(duì)我來(lái)說(shuō),理解起來(lái)相當(dāng)復(fù)雜。計(jì)數(shù)和計(jì)數(shù) == 4 的目的是什么?為什么在最后收盤?代碼提示無(wú)法訪問(wèn) 。在此之前,這個(gè)功能運(yùn)行良好。但最近或可能返回一些錯(cuò)誤,這會(huì)破壞代碼,這個(gè)fuc似乎被完全阻止了。你能幫我理解代碼,找到潛在的問(wèn)題并重構(gòu)這部分嗎?longTimeTask1()wg.Wait()longTimeTask1()longTimeTask2()
查看完整描述

2 回答

?
茅侃侃

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

查看 ,代碼似乎期望從通道接收四條消息。但是,此代碼最多可以從兩個(gè) goroutine 生成兩個(gè)這樣的消息,因此這是一個(gè)錯(cuò)誤。countdone


此外,如果任何一個(gè) goroutine 返回錯(cuò)誤,它就不會(huì)寫入通道,所以這是另一個(gè)錯(cuò)誤。done


另一種寫法可能是:


...

result := "processed"

for {

    select {

       case err := <-errc:

          close(quit) // Tell the goroutines to terminate

          log.Info("event: %s, %s", "", err.Error())

          wg.Wait() // Wait for them to finish

          return "", err

  

       case <-done:

          count++

          if count == 2 {

              wg.Wait()

              return result, nil

          }    

}


查看完整回答
反對(duì) 回復(fù) 2022-10-04
?
肥皂起泡泡

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

這正是 errgroup 包設(shè)計(jì)用于的分叉和聯(lián)接并發(fā)類型:


func processEvent(ctx context.Context, i models.Foo) (string, error) {

    err := func1()

    if err != nil {

        return "", err

    }


    g, ctx := errgroup.WithContext(ctx)


    if strings.ToUpper(i.Status) != "OK" {

        return "", nil

    }


    g.Go(func() error { return longTimeTask1(ctx) })

    g.Go(func() error { return longTimeTask2(ctx) })


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

        log.Printf("event: %v", err)

        return "", err

    }

    return "processed", nil

}

(https://play.golang.org/p/JNMKftQTLGs)


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

添加回答

舉報(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)