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

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

Golang - Go 例程和通道有一些問題

Golang - Go 例程和通道有一些問題

Go
慕村225694 2023-04-24 16:31:54
我對 Golang 有點陌生,正在嘗試開發一個將圖像異步上傳到 imgur 的程序。但是我的代碼遇到了一些困難。所以這是我的任務;func uploadT(url string,c chan string, d chan string)  {    var subtask string    subtask=upload(url)    var status string    var url string    if subtask!=""{        status = "Success!"        url =subtask    } else {        status = "Failed!"        url =subtask    }    c<-url    d<-status}這是我用于異步上傳的 POST 請求循環;c:=make(chan string, len(js.Urls))d:=make(chan string, len(js.Urls))wg:=sync.WaitGroup{}for i := range js.Urls{    wg.Add(1)    go uploadTask(js.Urls[i],c,d)    //Below commented out code is slowing down the routine therefore, I commented out.    //Needs to be working as well, however, it can work if I put this on task as well. I think I'm kinda confused with this one as well    //pol=append(pol,retro{Url:<-c,Status:<-d})}<-c<-dwg.Done()FinishedTime := time.Now().UTC().Format(time.RFC3339)qwe=append(qwe,outputURLs{               jobID:jobID,               retro:pol,               CreateTime: CreateTime,               FinishedTime: FinishedTime,           })fmt.Println(jobID)所以我覺得我的渠道和套路不行。它確實在上傳任務之前打印出 jobID。而且上傳對于異步上傳來說似乎太慢了。我知道代碼有點亂,對此感到抱歉。非常感謝任何幫助!提前致謝!
查看完整描述

2 回答

?
Cats萌萌

TA貢獻1805條經驗 獲得超9個贊

你實際上沒有WaitGroup正確使用。每次你調用wg.Done()它實際上是從前一個中減去 1wg.Add以確定給定的任務已完成。最后,您需要wg.Wait()同步等待所有任務。WaitGroups通常用于并行運行多個任務的扇出使用。


根據您的代碼示例,最簡單的方法是將 傳入wg您的任務,然后在任務內部uploadT調用。wg.Done()請注意,您還需要使用指針而不是結構值。


下一個實現細節是在循環外調用wg.Wait(),因為你想阻塞直到所有任務都完成,因為你的所有任務都在運行,go這使得它異步。如果你不這樣做wg.Wait(),它會像你說的那樣立即記錄jobID。讓我知道是否清楚。


作為樣板,它應該看起來像這樣


func task(wg *sync.WaitGroup) {

    wg.Done()

}


wg := &sync.WaitGroup{}

for i := 0; i < 10; i++ {

    wg.Add(1)

    go task(wg)

}


wg.Wait()

// do something after the task is done

fmt.Println("done")

我要注意的另一件事是,在您當前的代碼示例中,您正在使用通道,但您沒有對推送到通道中的值做任何事情,因此您可以從技術上刪除它們。


查看完整回答
反對 回復 2023-04-24
?
翻閱古今

TA貢獻1780條經驗 獲得超5個贊

你的代碼有點混亂。但是,如果我理解正確你正在嘗試做什么,你正在處理一個請求列表,并希望返回每個請求的 url 和狀態以及每個請求完成的時間。并且您想并行處理這些。


您根本不需要使用 WaitGroups。當您只想運行一堆任務而不關心結果,只想知道一切何時完成時,WaitGroups 非常有用。但如果你要返回結果,渠道就足夠了。


這是一個示例代碼,可以執行我認為您正在嘗試執行的操作


package main


import (

    "time"

    "fmt"

)


type Result struct {

    URL      string

    Status   string

    Finished string

}


func task(url string, c chan string, d chan string) {

    time.Sleep(time.Second)

    c <- url

    d <- "Success"

}


func main() {

    var results []Result

    urls := []string{"url1", "url2", "url3", "url4", "url5"}

    c := make(chan string, len(urls))

    d := make(chan string, len(urls))

    for _, u := range urls {

        go task(u, c, d)

    }

    for i := 0; i < len(urls); i++ {

        res := Result{}

        res.URL = <-c

        res.Status = <-d

        res.Finished = time.Now().UTC().Format(time.RFC3339)

        results = append(results, res)

    }

    fmt.Println(results)

}

你可以在操場上試試https://play.golang.org/p/N3oeA7MyZ8L


也就是說,這有點脆弱。您正在制作與網址列表大小相同的頻道。這對于一些 url 來說效果很好,但是如果你有一個包含一百萬個 url 的列表,你將創建一個相當大的頻道。您可能希望將通道緩沖區大小固定為某個合理的值,并在發送請求之前檢查通道是否已準備好進行處理。這樣你就可以避免一次發出一百萬個請求。


查看完整回答
反對 回復 2023-04-24
  • 2 回答
  • 0 關注
  • 132 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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