英文:
How can I edit my code to concurrency using in Go?
问题
我有一个名为getIPSetInfo的函数,它根据IpsetInfo数组中的元素数量进行多次HTTP请求。我该如何重新设计我的函数以使用多线程?我希望循环中的所有查询可以并行执行。
type IpsetInfo struct {
    OrgRef               ObjDesc  `json:"orgRef"`
    EdgeGatewayRef       ObjDesc  `json:"edgeGatewayRef"`
    OwnerRef             ObjDesc  `json:"ownerRef"`
    NetworkProviderScope string   `json:"networkProviderScope"`
    Status               string   `json:"status"`
    Id                   string   `json:"id"`
    Name                 string   `json:"name"`
    Description          string   `json:"description"`
    Type                 string   `json:"type"`
    IpAddresses          []string `json:"ipaddresses"`
}
func getIPSetInfo(ipsetIds []string) []IpsetInfo {
    var result []IpsetInfo
    var wg sync.WaitGroup
    var mu sync.Mutex
    for i := range ipsetIds {
        wg.Add(1)
        go func(id string) {
            defer wg.Done()
            url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + id
            _, body := httpGet(url, map[string]string{
                "Authorization": "Bearer " + accessToken,
            })
            var x IpsetInfo
            json.Unmarshal([]byte(body), &x)
            mu.Lock()
            result = append(result, x)
            mu.Unlock()
        }(ipsetIds[i])
    }
    wg.Wait()
    return result
}
func main() {
    ipsetIds := getIPSetIDs()
    IPSets := getIPSetInfo(ipsetIds)
    // 下面的Terraform模板将从模板中创建
    tmpl, err := template.ParseFiles("ipsets.template")
    if err != nil {
        log.Fatal(err)
    }
    f, err := os.Create("result.tf")
    if err != nil {
        log.Println("create file: ", err)
        return
    }
    err = tmpl.Execute(f, IPSets)
    if err != nil {
        log.Print("execute: ", err)
        return
    }
    f.Close()
}
在重新设计的getIPSetInfo函数中,我使用了sync.WaitGroup和sync.Mutex来实现并行执行HTTP请求,并确保结果的安全访问。每个循环迭代都会启动一个goroutine来执行HTTP请求,并将结果添加到result切片中。sync.WaitGroup用于等待所有goroutine完成,而sync.Mutex用于保护result切片的并发访问。
英文:
I have a function getIPSetInfo that makes HTTP requests as many times as there are elements in  IpsetInfo array.
How can I redesign my function to use multithreading?
I need all those queries in loop to be done in parallel.
type IpsetInfo struct {
OrgRef               ObjDesc  `json:"orgRef"`
EdgeGatewayRef       ObjDesc  `json:"edgeGatewayRef"`
OwnerRef             ObjDesc  `json:"ownerRef"`
NetworkProviderScope string   `json:"networkProviderScope"`
Status               string   `json:"status"`
Id                   string   `json:"id"`
Name                 string   `json:"name"`
Description          string   `json:"description"`
Type                 string   `json:"type"`
IpAddresses          []string `json:"ipaddresses"`
}
func getIPSetInfo(ipsetIds []string) []IpsetInfo {
var result []IpsetInfo
for i := range ipsetIds {
url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + ipsetIds[i]
_, body := httpGet(url, map[string]string{
"Authorization": "Bearer " + accessToken,
})
var x IpsetInfo
json.Unmarshal([]byte(body), &x)
result = append(result, x)
}
return result
} 
func main() {
ipsetIds := getIPSetIDs()
IPSets := getIPSetInfo(ipsetIds)
// Below terraform manifest will be created from template 
tmpl, err := template.ParseFiles("ipsets.template")
if err != nil {
log.Fatal(err)
}
f, err := os.Create("result.tf")
if err != nil {
log.Println("create file: ", err)
return
}
err = tmpl.Execute(f, IPSets)
if err != nil {
log.Print("execute: ", err)
return
}
f.Close()
}
答案1
得分: 3
也许这可以帮助你:
func getIPSetInfo(ipsetIds []string) []IpsetInfo {
    mu := &sync.Mutex{}
    var wg sync.WaitGroup
    
    var result []IpsetInfo
    
    call := func(val string){
        defer wg.Done()
        
        url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
        _, body := httpGet(url, map[string]string{
            "Authorization": "Bearer " + accessToken,
        })
        var x IpsetInfo
        json.Unmarshal([]byte(body), &x)
        
        mu.Lock()
        defer mu.Unlock()
        
        result = append(result, x)
    }
    
    for _, val := range ipsetIds {
        wg.Add(1)
        go call(val)
    }
    wg.Wait()
    return result
} 
希望对你有帮助!
英文:
Maybe this could help
func getIPSetInfo(ipsetIds []string) []IpsetInfo {
mu := &sync.Mutex{}
var wg sync.WaitGroup
var result []IpsetInfo
call := func(val string){
defer wg.Done()
url := "https://api-cloud-platform.com/cloudapi/1.0.0/firewallGroups/" + val
_, body := httpGet(url, map[string]string{
"Authorization": "Bearer " + accessToken,
})
var x IpsetInfo
json.Unmarshal([]byte(body), &x)
mu.Lock()
defer mu.Unlock()
result = append(result, x)
}
for _, val := range ipsetIds {
wg.Add(1)
go call(val)
}
wg.Wait()
return result
} 
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论