go语言中goroute使用:=遇到的坑

先看下源代码,预想从1至N总取出所有能被a或b整除的正整数之和,为了利用go语言的并行优势,特使用goroute特性来实现,同时使用普通顺序计算进行效率比较分析

package chango

import (
"fmt"
"time"
)

func get_sum_of_divisible(num int64, divider int64, resultChan chan int64) {
var sum int64 = 0
var value int64
for value = 1; value < num; value++ {
if value%divider == 0 {
sum += value
}
}
resultChan <- sum
}
func Zhengchu_testing(limit int64, one int64, two int64) {
resultchan := make(chan int64, 3)
var three int64
three = one * two

t_start := time.Now()

go get_sum_of_divisible(limit, one, resultchan)
go get_sum_of_divisible(limit, two, resultchan)
go get_sum_of_divisible(limit, three, resultchan)

one_sum, two_sum, three_sum := <-resultchan, <-resultchan, <-resultchan

var sum int64
var value int64
sum = one_sum + two_sum - three_sum

fmt.Println(sum)
t_end := time.Now()
fmt.Println(one_sum, two_sum, three_sum)
fmt.Printf("testing times1:%v\n", t_end.Sub(t_start))

sum = 0
t_start = time.Now()

for value = 1; value < limit; value++ {
if value%one == 0 {
sum += value

}
if value%two == 0 {
sum += value
}
if value%three == 0 {
sum -= value
}
}
fmt.Println(sum)
t_end = time.Now()
fmt.Printf("testing times2:%v\n", t_end.Sub(t_start))
}
然后在main包中调用该chango包
package main

import "./chango"

func main(){

chango.Zhengchu_testing(10,3,5)
}

初看上去,chango包没有语法毛病,但是实际测试发现,显然通过顺序计算10以内能被3或5整除的所有正整数分别为3,5,6,9,他们之和应该为23,能被3整数的整数之和为3+6+9=18,能被5整除的正整数之和为5,能被3*15=15的正整数之和为0
而通过goroute计算10以内能被3或5整除的所有正整数之和却不是23,而是-13或13,这又是为什么呢?
通过调试发现,问题就出现在“:=”语句中
  one_sum, two_sum, three_sum := <-resultchan, <-resultchan, <-resultchan
多次运行
通过分别打印能被3或5或3*5=15的正整数之和,他们的结果竟然是0,18,5或0,5,18,这个结果竟然不唯一


既然是这个语句有问题,此路不通,暂时绕道行之

于是修改源代码如下:
package chango

import (
"fmt"
"time"
)

func get_sum_of_divisible(num int64, divider int64, resultChan chan int64) {
var sum int64 = 0
var value int64
for value = 1; value < num; value++ {
if value%divider == 0 {
sum += value
}
}
resultChan <- sum
}
func Zhenchu_testing(limit int64, one int64, two int64) {
   var three int64
three = one * two
numbers:=[3]int64{one,two,three}

var ch [3](chan int64)
for i := 0; i < 3; i++ {
ch[i] = make(chan int64)
}
t_start := time.Now()
for i:=0;i<3;i++{
go get_sum_of_divisible(limit, numbers[i], ch[i])
}

one_sum:=<-ch[0]
two_sum:=<-ch[1]
three_sum:=<-ch[2]
var sum int64
var value int64
sum = one_sum + two_sum - three_sum

fmt.Println(sum)
t_end := time.Now()
fmt.Println(one_sum, two_sum, three_sum)
fmt.Printf("testing times1:%v\n", t_end.Sub(t_start))

sum = 0
t_start = time.Now()

for value = 1; value < limit; value++ {
if value%one == 0 {
sum += value

}
if value%two == 0 {
sum += value
}
if value%three == 0 {
sum -= value
}

}
fmt.Println(sum)
t_end = time.Now()
fmt.Printf("testing times2:%v\n", t_end.Sub(t_start))
}

这下在main包中调用该chango包通过!

结下来分析goroute同普通顺序计算进行效率比较分析,开始当计算从1至N总取出所有能被a或b整除的正整数之和中N的N的数值比较小的情况下,goroute的并行出来优势没有发挥出来,
测试打印输出如下:
当N=20

  78 
  63 30 15
  testing times1:33.557µs
  78
  testing times2:2.382µs

当N的数值很大的情况下,如100000000,goroute的并行计算优势就发挥出来了!

  测试打印输出如下:
  2333333316666668
  1666666683333333 999999950000000 333333316666665
  testing times1:1.574445477s
  2333333316666668
  testing times2:2.199982414s


 

参考学习资料

 











posted @ 2018-05-27 18:47  中国人醒来了  阅读(529)  评论(0编辑  收藏  举报