'Mutex does not seem to be locking properly

I am just learning about mutexess. I thought the following program would return a total of 1000, but I am getting varied results, so I assume I am doing something wrong...

package main

import (
    "fmt"
    "sync"
)

var total int
var locker sync.RWMutex

func add() {
    for x := 1; x <= 100; x++ {
        locker.Lock()
        total += 1
        locker.Unlock()
    }
}

func main() {
    for x := 1; x <= 10; x++ {
        go add()
    }
    fmt.Printf("Total is %v\n", total)
}


Solution 1:[1]

Main function returns before gorutines finished their works, you should add sync.WaitGroup, this code works as you expected: https://play.golang.com/p/_OfrZae0soB

package main

import (
    "fmt"
    "sync"
)

var total int
var locker sync.RWMutex

func add(wg *sync.WaitGroup) {
    defer wg.Done()
    for x := 1; x <= 100; x++ {
        locker.Lock()
        total += 1
        locker.Unlock()
    }
}

func main() {
    var wg sync.WaitGroup
    for x := 1; x <= 10; x++ {
        wg.Add(1)
        go add(&wg)
    }
    wg.Wait()
    fmt.Printf("Total is %v\n", total)
}

Solution 2:[2]

You're not waiting for any of the goroutines you started to finish before checking the result. Use a WaitGroup to wait for all of them to complete.

Solution 3:[3]

You have a data race. Therefore, the results are undefined.

package main

import (
    "fmt"
    "sync"
)

var total int
var locker sync.RWMutex

func add() {
    for x := 1; x <= 100; x++ {
        locker.Lock()
        total += 1
        locker.Unlock()
    }
}

func main() {
    for x := 1; x <= 10; x++ {
        go add()
    }
    fmt.Printf("Total is %v\n", total)
}

Output:

$ go run -race racer.go
==================
WARNING: DATA RACE
Read at 0x0000005ba408 by main goroutine:
  runtime.convT2E64()
      /home/peter/go/src/runtime/iface.go:335 +0x0
  main.main()
      /home/peter/src/racer.go:23 +0x84

Previous write at 0x0000005ba408 by goroutine 14:
  main.add()
      /home/peter/src/racer.go:14 +0x76

Goroutine 14 (running) created at:
  main.main()
      /home/peter/src/racer.go:21 +0x52
==================
Total is 960
Found 1 data race(s)
exit status 66
$ 

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 oxana
Solution 2 hobbs
Solution 3 peterSO