博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Go语言实现并行分段求和计算
阅读量:6601 次
发布时间:2019-06-24

本文共 1918 字,大约阅读时间需要 6 分钟。

这个实例通过循环实现并行的分段求和计算,再把各个子段和加到总和中。

通过这个实例可以了解如何实现循环并行处理,以及有关的编程技巧。

但是这个程序是有问题的,因为可能发生变量访问冲突问题,导致计算结果不正确。这个程序是不稳定的,有时能够计算出不正确的结果,有时能够计算出正确结果。

程序中的变量sum是共享变量,需要使用同步用的互斥锁来保证计算的正确性。正解程序附在本博文的最后。

Go语言程序(不稳定,会出错):

// loopgoroutine project main.gopackage mainimport (	"fmt"	"runtime"	"time")const START = 1const LEN = 100const STEP = 1000var sum int64func main() {	fmt.Printf("%d\n", (int64(LEN*STEP) * (int64(LEN*STEP) + 1) / int64(2)))	sum = 0	start := START	for i := 1; i <= STEP; i++ {		go subsum(start, LEN)		start += LEN	}	for runtime.NumGoroutine() > 1 {		time.Sleep(100 * time.Millisecond)	}	fmt.Printf("%d\n", sum)}func subsum(start int, len int) {	var ssum int64	ssum = 0	for i := 1; i <= len; i++ {		ssum += int64(start)		start++	}	sum += ssum}

运行结果(可能是以下两种,也可能算出其他的结果):

50000500005000050000
50000500004713772650

程序说明:

1.这个程序总的功能是计算1到100000(LEN×STEP)的和,计算被分为STEP步(段)进行,通过调用函数subsum()计算每段之和,然后相加

2.函数subsum()计算从start开始长度为len的数列之和

3.语句"fmt.Printf("%d\n", (int64(LEN*STEP) * (int64(LEN*STEP) + 1) / int64(2)))"打印输出一个正确的结果作为参考值

4.为了知道程序当前有几个goroutine在运行,需要使用包"runtime",其中的方法runtime.NumGoroutine()返回正在运行的goroutine的数量,需要注意的是main()本身也是一个goroutine

5.使用包"time"中的方法time.Sleep(),让自身的goroutine休眠,代入参数指定休眠0.1秒,因为需要等待所有其他goroutine都执行完之后程序才能结束

6.使用互斥锁mu来锁住变量sum(参见程序),需要使用包"sync"

Go语言程序(正解):

// loopmutex project main.gopackage mainimport (	"fmt"	"runtime"	"sync"	"time")const START = 1const LEN = 100const STEP = 1000var (	mu  sync.Mutex	sum int64)func main() {	fmt.Printf("%d\n", (int64(LEN*STEP) * (int64(LEN*STEP) + 1) / int64(2)))	sum = 0	start := START	for i := 1; i <= STEP; i++ {		go subsum(start, LEN)		start += LEN	}	for runtime.NumGoroutine() > 1 {		time.Sleep(100 * time.Millisecond)	}	fmt.Printf("%d\n", sum)}func subsum(start int, len int) {	var ssum int64	ssum = 0	for i := 1; i <= len; i++ {		ssum += int64(start)		start++	}	mu.Lock()	sum += ssum	mu.Unlock()}

转载于:https://www.cnblogs.com/tigerisland/p/7563551.html

你可能感兴趣的文章
如何构建微服务架构
查看>>
【前端笔记】彻底理解变量与函数的声明提升
查看>>
PHP工具箱:PHPStan —— PHP 静态代码分析工具
查看>>
iOS - 多链式动画框架 LSAnimator
查看>>
Android 反编译利器,jadx 的高级技巧
查看>>
Mycat 读写分离 数据库分库分表 中间件 安装部署
查看>>
二叉搜索树(递归实现)
查看>>
Spring Retry重试机制
查看>>
Android官方架构组件LiveData: 观察者模式领域二三事
查看>>
第七章——字符串(不定长度字符)
查看>>
Cocoapods 创建第三方框架
查看>>
[Android组件化]组件化数据分享
查看>>
[转]23个最有用的Elasticsearch检索技巧
查看>>
你必须知道的HTTP基本概念
查看>>
当下拉列表数据过大时,该如何应对?
查看>>
使用OpenGrok搭建 可搜索可跳转的源码 阅读网站
查看>>
HTML5开发中的javascript闭包
查看>>
Android ContentProvider调用报错"Bad call:..."及相关Binder权限问题分析
查看>>
你真的会用strong-weak dance吗?
查看>>
ionic3 教程(二)登录页制作
查看>>