douding7189 2016-12-28 06:12
浏览 21
已采纳

为什么`sync.WaitGroup`无法完成?

Here is my code:

package main

import (
    "bytes"
    "crypto/md5"
    "encoding/hex"
    "encoding/json"
    "fmt"
    "io/ioutil"
    "log"
    "net/http"
    "runtime"
    "sync"
)

type Data struct {
    Link string `json:"url"`
}
type Result struct {
    Code uint32
    Msg  string `json:"msg"`
    Data Data   `json:"data"`
}

const (
    URL     = "http://qiye.wxsdc.ediankai.com/api/v1/suppliers/1/staff/1/box/get"
    SIGNKEY = "i5OqMrNXVyOJ5GEMYoEtRHqN1P9ghk6I"
    DATA_ID = "2965612126"
    EQU_ID  = "1482806063"
)

func getMD5Hash(text string) string {
    hasher := md5.New()
    hasher.Write([]byte(text))
    return hex.EncodeToString(hasher.Sum(nil))
}

func getUrl(payload []byte, wg *sync.WaitGroup, result chan string) {
    req, err := http.NewRequest("POST", URL, bytes.NewBuffer(payload))
    req.Header.Set("Content-Type", "application/json")

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
        panic(err)
    }
    defer resp.Body.Close()

    body, err := ioutil.ReadAll(resp.Body)
    if err != nil {
        panic(err)
    }
    var res Result
    json.Unmarshal(body, &res)
    log.Println(res.Data.Link)
    result <- res.Data.Link
    wg.Add(-1)
}
func main() {
    parameterStr := fmt.Sprintf("%vdata_id%vequ_id%v%v", SIGNKEY, DATA_ID, EQU_ID, SIGNKEY)
    log.Println(parameterStr)
    sign := getMD5Hash(parameterStr)
    log.Println(sign)
    var payload map[string]string = make(map[string]string)
    payload["equ_id"] = EQU_ID
    payload["data_id"] = DATA_ID
    payload["sign"] = sign

    payloadJson, err := json.Marshal(payload)
    if err != nil {
        log.Fatalln("convet paylod failed!")
    }
    log.Println(string(payloadJson))

    runtime.GOMAXPROCS(runtime.NumCPU())
    var wg sync.WaitGroup
    result := make(chan string)
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go getUrl(payloadJson, &wg, result)
    }
    wg.Wait()
    for link := range result {
        fmt.Println(link)
    }
    log.Println("Done!")
}

But:

for link := range result {
    fmt.Println(link)
}
log.Println("Done!")

can't be executed, what's the reason?

  • 写回答

2条回答 默认 最新

  • dongyukang7006 2016-12-28 06:58
    关注

    You need to close the result channel so the for loop which reads from it is interrupted when its finished. For that you could rewrite the last part as:

    var wg sync.WaitGroup
    result := make(chan string)
    go func() {
        for link := range result {
            fmt.Println(link)
        }
    }()
    for i := 0; i < 10; i++ {
        wg.Add(1)
        go getUrl(payloadJson, &wg, result)
    }
    wg.Wait()
    close(result)
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 使用EMD去噪处理RML2016数据集时候的原理
  • ¥15 神经网络预测均方误差很小 但是图像上看着差别太大
  • ¥15 Oracle中如何从clob类型截取特定字符串后面的字符
  • ¥15 想通过pywinauto自动电机应用程序按钮,但是找不到应用程序按钮信息
  • ¥15 如何在炒股软件中,爬到我想看的日k线
  • ¥15 seatunnel 怎么配置Elasticsearch
  • ¥15 PSCAD安装问题 ERROR: Visual Studio 2013, 2015, 2017 or 2019 is not found in the system.
  • ¥15 (标签-MATLAB|关键词-多址)
  • ¥15 关于#MATLAB#的问题,如何解决?(相关搜索:信噪比,系统容量)
  • ¥500 52810做蓝牙接受端