zoukankan      html  css  js  c++  java
  • Go语言实现并行分段求和计算

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

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

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

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


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

    // loopgoroutine project main.go
    package main
    
    import (
    	"fmt"
    	"runtime"
    	"time"
    )
    
    const START = 1
    const LEN = 100
    const STEP = 1000
    
    var sum int64
    
    func main() {
    	fmt.Printf("%d
    ", (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
    ", sum)
    }
    
    func subsum(start int, len int) {
    	var ssum int64
    	ssum = 0
    	for i := 1; i <= len; i++ {
    		ssum += int64(start)
    		start++
    	}
    
    	sum += ssum
    }

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

    5000050000
    5000050000
    5000050000
    4713772650

    程序说明:

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

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

    3.语句"fmt.Printf("%d ", (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.go
    package main
    
    import (
    	"fmt"
    	"runtime"
    	"sync"
    	"time"
    )
    
    const START = 1
    const LEN = 100
    const STEP = 1000
    
    var (
    	mu  sync.Mutex
    	sum int64
    )
    
    func main() {
    	fmt.Printf("%d
    ", (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
    ", 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()
    }



  • 相关阅读:
    node中fs模块
    node生成excel,动态替换表格内容
    Postgresql存放数组形式的数据
    ubuntu下安装typescript
    随笔6
    excel文件导出相应数据统计内容
    随笔4
    随笔3.2
    随笔2
    随笔1
  • 原文地址:https://www.cnblogs.com/tigerisland/p/7563551.html
Copyright © 2011-2022 走看看