```
package main
import (
"encoding/json"
"log"
"sync"
)
var ResData []ItemData
var ch = make(chan ItemData)
func do(u UserRes,item ItemData,p Param, waitGroup *sync.WaitGroup) {
defer waitGroup.Done()
//do something 5-10s
item.money_total = 1
ch<-item
}
func main() {
sql := "SELECT id FROM user limit 10000"
rows, err := dbCon.Queryx(sql)
if err != nil {
log.Fatalf("err: %v", err)
}
defer rows.Close()
var wg sync.WaitGroup
for rows.Next() {
wg.Add(1)
var u UserRes
var item ItemData
err = rows.StructScan(&u)
if err != nil {
log.Fatalf("err: %v", err)
}
go do(u,item,p,&wg)
ResData = append(ResData,<- ch)
}
json, err := json.Marshal(ResData)
if err != nil {
log.Fatalf("JSON ERR: %v", err)
}
wg.Wait()
}
```
这上面是部分代码示意
大概需求就是我需要给每个用户生成一份报表。每个用户生成时间大概就是5-10s,但是用户比较多
然后我发现我这样写好像还是需要很久的时间才能全部处理完
感觉是我对哪块的理解有问题或者是哪里阻塞了。
或者大佬们一般这种任务是怎么处理的。用什么组件
解决办法:将 ResData = append(ResData,<- ch)操作放到for循环外。
原因:ch是无缓存的cahnnel,所以 <- ch操作会阻塞,直到ch中有数据才会执行,所以ResData = append(ResData,<- ch)会阻塞for循环,既这里的go do()并没有实现真正的并发执行,实际是串行执行操作
#6
更多评论
```go
ch<-item
ResData = append(ResData,<- ch)
```
这是个无缓存的chan,必须发送/接受结束才会下一步。
可以带个缓存试试。若要存储执行结果,可以用sync.map。
#1