golang如何实现并发求和

  介绍

这篇文章主要介绍了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   null

golang如何实现并发求和