介绍
这篇文章主要介绍了golang如何实现并发求和,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获、下面让小编带着大家一起了解一下。
golang适合做什么
golang可以做服务器端开发,但golang很适合做日志处理,数据打包,虚拟机处理,数据库代理等工作。在网络编程方面,它还广泛应用于网络应用,API应用等领域。
使用golang并发求和,作为对golang并发的一个练习。
为了验证结果的正确性,要给出最传统的版本:
func sum1 (data int []), int { ,s :=0 ,l :=, len(数据) ,for 小姐::=,0;,小姐:& lt;, l;,我+ +,{ +=s 才能;数据(我) ,} return 年代 }
第二种方法
使用N个goroutine,然后将N个分段的和写入N个频道中:
func sum2 (data int []), int { ,s :=0 ,l :=, len(数据) ,const N =5 ,seg :=, l /N ,var chs [N] & lt; -chan int ,for 小姐::=,0;,小姐:& lt;, N;,我+ +,{ chs才能[我],=,工人(数据(我* seg :, (i + 1) *赛格]) ,} ,for 小姐::=,0;,小姐:& lt;, N;,我+ +,{ +=s 才能;& lt; chs[我] ,} return 年代 } func 工人(s int []), & lt; -chan int { ,out :=, (chan int) ,go func (), { length 才能;:=,len (s) sum 才能:=0 for 才能;小姐::=,0;,小姐:& lt;,长度;,我+ +,{ ,,sum +=, s[我] ,,} out 才能;& lt;作用;和 ,}() return 了 }
对于一个求和的任务来说,用工人这种“模式”可能太过麻烦,
看第三种
直接一个函数写出来:
func sum3 (data int []), int { ,s :=0 ,l :=, len(数据) ,const N =5 ,seg :=, l /N var mu sync.Mutex var wg sync.WaitGroup ,wg.Add (N),//,直接加N个 ,for 小姐::=,0;,小姐:& lt;, N;,我+ +,{ go 才能;func (ii int), { ,,tmpS :=,数据(时间:2 * seg (2 + 1) *赛格] ,,ll :=, len (tmp) ,,mu.Lock () ,,for 小姐::=,0;,小姐:& lt;,我,,我+ +,{ ,,,s +=, tmp[我] ,,} ,,mu.Unlock () ,,wg.Done(),//,一个goroutine运行完 }(i)才能 ,} ,wg.Wait(),//,等N个goroutine都运行完 return 年代 }
注意sum3要在读写年代的地方加锁,因为年代可能被多个goroutine并发读写。
最后一种方法有数据竞赛问题
不过运行结果是对的,看一下思路:
var sum4Tmp int var sum4mu  sync.Mutex//,这个有data 种族问题,可以用WaitGroup改,只是提供一种思路 func sum4 (data int []), int { ,//s :=0 ,l :=, len(数据) ,const N =5 ,seg :=, l /N ,for 小姐::=,0;,小姐:& lt;, N;,我+ +,{ go 才能subsum4(数据(我* seg :, (i + 1) *赛格]) ,} ,//这里是在1,因为要排除主要 ,//这种方法不可靠,只是一种思路 ,for runtime.NumGoroutine(),祝辞,1,{ ,} ,//go run  -race sum.go会报data 种族问题 ,//main goroutine对它读 ,//别的goroutine会对它写(go subsum4) return sum4Tmp } func subsum4 (s int []), { ,length :=, len (s) ,sum :=0 ,sum4mu.Lock () ,for 小姐::=,0;,小姐:& lt;,长度;,我+ +,{ +=sum 才能;s[我] ,}=,,sum4Tmp  sum4Tmp +总和 ,defer sum4mu.Unlock () }
最后测试如下:
首先创建一个切片,放1 e8(1亿)个整数(范围[0,10))进去,
然后用4种方法进行计算
func calcTime (f func (int []), int,, arr int [],, tag 字符串),{ ,t1 :=, time.Now () .UnixNano () ,s :=, f (arr) ,t2 :=, time.Now () .UnixNano(),背后,t1 ,fmt.Printf (“% 15 s:时间:,% d,,和,,% d \ n",,标签,t2,,) } func main (), { ,const MAX =, 1 e8 //1个亿 ,arr :=, (int[],马克斯) ,for 小姐::=,0;,小姐:& lt;, MAX;,我+ +,{ 加勒比海盗才能[我],=,rand.Intn (10) ,} ,calcTime (arr sum1,,,,“for") ,calcTime (arr sum2,,,,“worker") ,calcTime (arr sum3,,,,“WaitGroup") ,calcTime (arr sum4,,,,“NumGoroutine") null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null null nullgolang如何实现并发求和