详解Go 并发
golang天生语言层面支持并发,非常棒的语言,有时我们业务开发时,遇到复杂场景,需要用于并发,将多个请求使用协程组完成并发,当遇到嵌套循环,还存在上下文关系需要改造为并发请求,将之前的时间复杂度为O(n^2)改为O(n)的时间复杂度,那是否还能否并时间复杂度进一步降为O(1)呢?就出现嵌套并发.具体如何嵌套并发,如何写.今天就一步一步分析.
串行执行
- 时间复杂度为O(n^2)
- 不使用并发
- 结果执行时间为9s
//串行执行
funcSerializeRun(){
start:=time.Now()
xx:=[]int{1,2,3}
yy:=[]int{100,200,300}
for_,x:=rangexx{
for_,y:=rangeyy{
abc(x,y)
}
}
fmt.Printf("串行执行总时间:%s\n",time.Since(start))
}
funcabc(x,yint){
time.Sleep(time.Second*1)
fmt.Printf("x:%d,y:%d\n",x,y)
}
执行结果
x:1,y:100
x:1,y:200
x:1,y:300
x:2,y:100
x:2,y:200
x:2,y:300
x:3,y:100
x:3,y:200
x:3,y:300
串行执行总时间:9.0026338s
单协程组并发
- 使用了协程组将O(n^2)降为O(n)
- 结果执行时间为3s
//单并行执行
funcSingleConcurrenceRun(){
start:=time.Now()
xx:=[]int{1,2,3}
yy:=[]int{100,200,300}
for_,x:=rangexx{
wgg:=sync.WaitGroup{}
for_,y:=rangeyy{
wgg.Add(1)
gofunc(x,yint){
deferwgg.Done()
abc(x,y)
}(x,y)
}
wgg.Wait()
}
fmt.Printf("单并行执行总时间:%s\n",time.Since(start))
}
funcabc(x,yint){
time.Sleep(time.Second*1)
fmt.Printf("x:%d,y:%d\n",x,y)
}
结果
x:1,y:300
x:1,y:200
x:1,y:100
x:2,y:100
x:2,y:200
x:2,y:300
x:3,y:300
x:3,y:100
x:3,y:200
单并行执行总时间:3.0013813s
嵌套并发执行
- 使用嵌套协程组执行并发.
- 将O(n^2)降到O(1)
- 结果执行时间为1s
//嵌套执行
funcNestConcurrenceRun(){
xx:=[]int{1,2,3}
yy:=[]int{100,200,300}
start:=time.Now()
wgg:=sync.WaitGroup{}
for_,x:=rangexx{
wgg.Add(1)
gofunc(xint){
wg:=sync.WaitGroup{}
for_,y:=rangeyy{
wg.Add(1)
gofunc(x,yint){
deferwg.Done()
abc(x,y)
}(x,y)
}
wg.Wait()
wgg.Done()
}(x)
}
wgg.Wait()
fmt.Printf("嵌套并发执行总时间:%s\n",time.Since(start))
}
funcabc(x,yint){
time.Sleep(time.Second*1)
fmt.Printf("x:%d,y:%d\n",x,y)
}
结果
x:1,y:200
x:3,y:300
x:3,y:200
x:1,y:300
x:2,y:200
x:1,y:100
x:2,y:300
x:2,y:100
x:3,y:100
嵌套并发执行总时间:1.0023542s
以上就是详解Go并发的详细内容,更多关于Go并发的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。