带有sync.waitGroup的Goroutine每次输出不同的值

问题描述

下面的代码每次执行后都会打印不同的值,但是我希望这些值相同,如何在不使用time.Sleep的情况下更改下面的代码

package main

import (
    "fmt"
    "sync"
)

var total int
var wg sync.WaitGroup

// Inc increments the counter for the given key.
func inc(num int) {
    total += num
    wg.Done()
}

// Value returns the current value of the counter for the given key.
func getValue() int {
    return total
}

func main() {
    for i := 1; i <= 1000; i++ {
        wg.Add(1)
        go inc(i)
    }
    wg.Wait()
    fmt.Println(getValue())
}

解决方法

每次获得不同价值的原因是total += num中的比赛条件。

一个简单的解决方法是添加互斥锁: var mu sync.Mutex

并在inc 中使用它:

func inc(num int) {
    mu.Lock()
    defer mu.Unlock()
    total += num
    wg.Done()
}
,

您正在进行数据竞赛,结果不确定。您必须同步对share变量的访问:

var total int
var lock sync.Mutex
var wg sync.WaitGroup

// Inc increments the counter for the given key.
func inc(num int) {
    lock.Lock()
    defer lock.Unlock()
    total += num
    wg.Done()
}

// Value returns the current value of the counter for the given key.
func getValue() int {
    lock.Lock()
    defer lock.Unlock()
    return total
}

或者,使用sync/atomic访问/修改变量。

,

已经提到您具有“数据竞争”,使用Mutex是一种解决方案。另外,您可以使用atomic软件包,该软件包更快。

package main

import (
    "fmt"
    "sync"
    "sync/atomic"
)

var total uint64
var wg sync.WaitGroup

func inc(num uint64) {
    atomic.AddUint64(&total,1)
    wg.Done()
}

// Value returns the current value of the counter for the given key.
func getValue() uint64 {
    return atomic.LoadUint64(&total)
}

func main() {
    for i := uint64(1); i <= 1000; i++ {
        wg.Add(1)
        go inc(i)
    }
    wg.Wait()
    fmt.Println(getValue())
}

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...