详解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(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。