协程+有缓冲通道累加和for循环累加结果不一致?

想请教一下为什么两种方法打印的结果addResult 不一致;
1、一种是启动协程+有缓冲通道去累加10000范围内的质数
2、另一个是直接for循环去计算

如果方法1只启动一个协程,那就结果是一致的。

package main

import (
    "fmt"
    "sync"
    "time"
)

func main() {
    num := 10000
    startTime := time.Now().UnixNano() / int64(time.Millisecond)
    channelAdd(num, 4)
    endTime := time.Now().UnixNano() / int64(time.Millisecond)
    fmt.Println(endTime - startTime)

    startTime = time.Now().UnixNano() / int64(time.Millisecond)
    forAdd(num)
    endTime = time.Now().UnixNano() / int64(time.Millisecond)
    fmt.Println(endTime - startTime)
}

func channelAdd(n int, c int) int {
    var sync sync.WaitGroup
    var chans = make(chan int, 4)
    sync.Add(c)
    var addResult int
    for i := 0; i < c; i++ {
        go func(work int) {
            defer sync.Done()
            for {
                data, ok := <-chans
                if !ok {
                    break
                }
                if isPrime(data) {
                    // fmt.Println(data)
                    addResult += 1
                }
            }
        }(i)
    }
    for i := 1; i < n; i++ {
        chans <- i
    }
    close(chans)
    sync.Wait()
    fmt.Println(addResult)
    return addResult
}

func forAdd(n int) int {
    var addResult int
    for i := 1; i < n; i++ {
        if isPrime(i) {
            addResult += 1
        }
    }
    fmt.Println(addResult)
    return addResult
}

// 判断n是不是质数
func isPrime(n int) bool {
    if n <= 1 {
        return false
    }
    for i := 2; i < n; i++ {
        if n%i == 0 {
            return false
        }
    }
    return true
}
野生菌
最佳答案

file
出现了 data race, 截图哪里加个锁就能解决

2年前 评论
野生菌 (楼主) 2年前
讨论数量: 2

file
出现了 data race, 截图哪里加个锁就能解决

2年前 评论
野生菌 (楼主) 2年前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!