用 goroutine 写了 3 种,得到的结果都不一样,不知道为什么?

请教一个问题 我用 go 写了一个小脚本,批量请求快一万个请求,处理数据。用 goroutine 写了 3 种,得到的结果都不一样,不知道为什么,求教

FetchProductpage 是一次 http 请求
gidsList 是一个 []string,存放 id
func FetchProductpage(ch chan<- string) {
    req := &fasthttp.Request{}
    req.SetRequestURI("http://abc.com")
    req.Header.SetContentType("application/json")
    req.Header.SetMethod("POST")
    res := &fasthttp.Response{}
    if err := fasthttp.Do(req, res); err != nil {
        panic(reqBody[0].Gid + "handle error")
    }

    resBody := res.Body()

    var list []int
    json.Unmarshal(resBody, &list)
    if len(list) == 0 {
        ch <- reqBody[0].Gid
    }

    ch <- ""
}
// 法一 直接 panic
ch := make(chan string)
defer close(ch)

for index, gid := range gidsList {
    go func(index int, gid string) {
        println("第 ", index, " 个商品:", gid)
        FetchProductpage(ch)
    }(index, gid)
}

for range gidsList {
    noGid := <-ch
    if noGid != "" {
        noGidsLen++
    }
}
println("其中 ", noGidsLen, " 个没有结果")

image.png

// 法二 用了 10 分钟
ch := make(chan string)
defer close(ch)

go func() {
    for _, gid := range gidsList {
        println("第 ", index, " 个商品:", gid)
        FetchProductpage(ch)
    }
}()

for range gidsList {
    noGid := <-ch
    if noGid != "" {
        noGidsLen++
    }
}
println("其中 ", noGidsLen, " 个没有结果")
// 法三 只用了2分钟
ch := make(chan string)
defer close(ch)

for index, gid := range gidsList {
    go func(index int, gid string) {
        println("第 ", index, " 个商品:", gid)
        FetchProductpage(ch)
    }(index, gid)

    noGid := <-ch
    if noGid != "" {
        noGidsLen++
        f.WriteString(noGid + "\n")
    }
}

println("其中 ", noGidsLen, " 个没有结果")

第一种写法为什么会 panic ?

第二种和第三种的区别在哪呢?为什么时间会差这么多?

阅读 2.3k
1 个回答

方法1 为什么panic?
panic(reqBody[0].Gid + "handle error:" + err)
把err 打印出来,看是什么情况。

方法2和方法3 的差别为什么查那么多?
go func() {

for _, gid := range gidsList {
    println("第 ", index, " 个商品:", gid)
    FetchProductpage(ch)
}

}()
你这是启动一个协程跑来处理,for 里面相当于串行化处理、
而方法3 并行处理FetchProductpage。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题