Please can some one tell me why this dosent work

Hi My name is Sean and I have recently started learning Golang however I have come across an issue with concurrent code:

I have two functions running but they share the variable COUNTER and it is causing a race condition ?

I have attempted to lock this down with both GoRoutienes and Mutex but still get a race ?

can you please take a look at the code bellow and see why:

package main

import (
“fmt”
“runtime”
“sync”
)

var counter int
var wg sync.WaitGroup
var mutex = sync.Mutex{}
var mutex2 = sync.Mutex{}

func main() {
fmt.Println(“CPU count Start: \t”, runtime.NumCPU())
fmt.Println(“GoRoutines count Start: \t”,runtime.NumGoroutine())

wg.Add(2)

go boo()
go bar()

wg.Wait()

fmt.Println(“GoRoutines count End: \t”,runtime.NumGoroutine())
fmt.Println(“the end : :)”)

}

func boo() int {
i := 0
for i = 0; i < 10; i++{
mutex.Lock()
counter++
fmt.Println(“count of boo: \t”, counter)
mutex.Unlock()
}
wg.Done()
return counter
}

func bar() int {
i := 0
for i = 0; i < 10; i++ {
mutex2.Lock()
counter += 2
fmt.Println(“count of bar: \t”, counter)
mutex2.Unlock()
}
wg.Done()
return counter
}

I have worked out if I delay the one function with the time.sleep it will run but is this then not concurrent code?

func bar() int {
time.Sleep(time.Nanosecond *1)
i := 0
for i = 0; i < 10; i++ {
mutex2.Lock()
counter += 2
fmt.Println(“count of bar: \t”, counter)
mutex2.Unlock()
}
wg.Done()
return counter
}

Can’t wait to here all your opinions on the above and really appreciate and assistance on this as I have only been coding for 3wks and finding it hard to understand it fully

Many Thanks,

Sean.

Use one mutex

package main

import (
	"fmt"
	"runtime"
	"sync"
)

var counter int
var wg sync.WaitGroup
var mutex = sync.Mutex{}

func main() {
	fmt.Println("CPU count Start: \t", runtime.NumCPU())
	fmt.Println("GoRoutines count Start: \t", runtime.NumGoroutine())

	wg.Add(2)

	go boo()
	go bar()

	wg.Wait()

	fmt.Println("GoRoutines count End: \t", runtime.NumGoroutine())
	fmt.Println("the end : :)")

}

func boo() int {
	defer wg.Done()
	i := 0
	for i = 0; i < 10; i++ {
		mutex.Lock()
		counter++
		fmt.Println("count of boo: \t", counter)
		mutex.Unlock()
	}
	mutex.Lock()
	defer mutex.Unlock()
	return counter
}

func bar() int {
	defer wg.Done()
	i := 0
	for i = 0; i < 10; i++ {
		mutex.Lock()
		counter += 2
		fmt.Println("count of bar: \t", counter)
		mutex.Unlock()
	}
	mutex.Lock()
	defer mutex.Unlock()
	return counter
}

Hi Mikoj,

Thank you for your reply, I have tried it with one Mutex and it still has a race condition, can I ask as to why you are using a mutex.Lock() and defer with nothing inside the mutex ?

As i said previously in the post you can delay one of the functions and it works however would this really be parallel code ?

many thanks for your help in assisting me in my understanding.

Sea.

nothing inside hmm, no i have return code inside.
first you need to know how it works defer
https://blog.golang.org/defer-panic-and-recover
https://medium.com/a-journey-with-go/go-how-does-defer-statement-work-1a9492689b6e

see this video
https://www.youtube.com/watch?v=cN_DpYBzKso

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.