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

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

孩子的價值打印在延遲后成為常規

孩子的價值打印在延遲后成為常規

Go
夢里花落0921 2022-11-23 13:56:22
我正在從我的驅動程序代碼中生成 5 個工作池,并從工作池返回錯誤。在我的主要任務中,我有另一個 go routine(go routine A ,在那個 go routine 之上添加了注釋)監聽錯誤。但是當從我的錯誤通道中選取數據時,我的 defer 語句正在執行。但我仍然可以看到來自 go routine A 的日志。func ....{var requests []Req        err := json.Unmarshal(Data, &requests)        if err != nil {            log.WithError(err).Errorf("Invalid data passed for flag type %v", proto.CreateFlagReq_SET_OF.String())            return err        }        f.Manager.TaskChan = make(chan Req, 100)        f.Manager.ErrorChan = make(chan error, 100)        for i := 0; i < f.Manager.WorkerCount; i++ {            f.Manager.Wg.Add(1)           //AddToSetOfcustomers just validates before addigg to redis            go f.Manager.Work(ctx, f.redisPool.AddToSetOfcustomers, i)        }        for _, request := range requests {            f.Manager.TaskChan <- request        }        close(f.Manager.TaskChan)        var errors error        **//go routine A**        go func() {            for {                select {                case err ,ok:= <- f.Manager.ErrorChan:                    if ok{                        errors = multierror.Append(errors, err)                        log.Errorf("got erro1r %v",errors)                    }else{                        log.Info("returning")                        return                    }                }            }        }()        f.Manager.Wg.Wait()        defer log.Errorf("blhgsgh   %v %v",len(f.Manager.ErrorChan),errors)        return errors}我有點懷疑 defer 被執行了,然后我的主要 go 例程完成了,然后 return 被執行了,但是我能做些什么來傳播我在返回之前從 multiErrors 附加的錯誤?如果我嘗試使用通道同步 go routine A 和我的主要 go routine(我稱之為 defer 的那個),它會變成阻塞。Help appretiated
查看完整描述

1 回答

?
千巷貓影

TA貢獻1829條經驗 獲得超7個贊

我已經在playground中簡化了您的代碼。

您似乎假設f.Manager.Wg.Wait()返回時所有錯誤都已處理。然而,錯誤正在一個單獨的 goroutine ( **//go routine A**) 中處理,您不會等待它完成——事實上,因為您不關閉f.Manager.ErrorChangoroutine 永遠不會完成。

解決這個問題的最簡單方法是等待 goroutine 退出,然后再從函數返回。下面的示例 ( playground ) 使用一個通道來執行此操作,但WaitGroup如果您愿意,也可以使用一個。

var errors []error

errDone := make(chan struct{})

go func() {

    for {

        select {

        case err, ok := <-errorChan:

            if ok {

                errors = append(errors, err)

                log.Printf("got error %v", errors)

            } else {

                log.Printf("returning")

                close(errDone)

                return

            }

        }

    }

}()

wg.Wait()


// Everything sending to errorChan is now done so we can safely close the channel

close(errorChan)

<-errDone // Wait for error handling goroutine to complete

請注意,defer“在周圍函數返回之前立即運行”。您啟動的任何 goroutine 都可以比該函數存活(它們不會自動停止)。



查看完整回答
反對 回復 2022-11-23
  • 1 回答
  • 0 關注
  • 81 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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