背景:go的并发控制也是老生常谈,在公司业务中也是经常出现
谈谈我们这次并发模型的适用场景:要处理的任务很多比如有10000个,没开并发的时候我们要一个一个进行执行这个时候其实无论是cpu压力还是数据库和redis压力都比较小也就是说它们现在还很闲,我们可以给它们加并发压榨cpu和数据库的工作效率
限制:理论上讲并发数小于任务数,总不能1000个任务开2000个并发,首先就像1000个馒头让2000个人去吃一样撤,其次是开2000个并发如果任务比较重那数据库也受不了报警
我给出的并发模型的可以通过修改channel的容量来控制并发数
接下来看代码
package main
import (
"fmt"
"sync"
"time"
)
func main() {
GNUM := 100 //携程并发数
ch := make(chan struct{}, GNUM)
wg := sync.WaitGroup{}
start := time.Now().Second() //记录开始时间
for i := 1; i <= 1000; i++ {
ch <- struct{}{}
wg.Add(1)
go func(i int) {
defer func() {
fmt.Printf("task%d执行完毕\n", i)
<-ch
wg.Done()
}()
fmt.Printf("执行task%d \n", i)
time.Sleep(1 * time.Second)
}(i)
}
wg.Wait()
close(ch)
end := time.Now().Second() //记录结束时间
fmt.Printf("并发数:%d 时 花费时间为:%d", GNUM, end-start) //输出处理任务的总时间 单位S
}
这个代码假设是每个任务执行时间是1秒如果我们不开并发执行1000个任务是1000秒但如果我们开100个并发只需要10秒 1000个并发只需要1秒 10个并发小于10秒