October 22, 2021

# Race conditions and mutex in GoLang

Sometimes we see the race conditions in our code. We can use mutex or channels to resolve those race conditions.
Lets see what is a race condition…

package main

import (
“fmt”
“time”
)

var x = 0

func myincrement() {
x = x + 1
}

func main() {
for i := 0; i < 1000; i++ {
go myincrement()
}
time.Sleep(1 * time.Second)
fmt.Println(“final value of x is”, x)
}

final value of x is 980

Here the output is:-
final value of x is 939
Here you will not get the output as 1000 all the time.
Here the problem is we have spawned 1000 Goroutines and each trying to increment the value of x by 1, which is a critical section and hence the race condition. But if we will do this increment one after another i,e in a sequential way or i,e in a synchronized way then the increment will be proper and we will get 1000 always.

Lets try to solve it using Mutex:-
A mutex provides a locking mechanism and make sure only one Goroutine is running the critical section at any moment of time.

package main

import (
“fmt”
“sync”
“time”
)

var x = 0

func myincrement(m *sync.Mutex) {
m.Lock()
x = x + 1
m.Unlock()
}
func main() {
var m sync.Mutex
for i := 0; i < 1000; i++ {
go myincrement(&m)
}
time.Sleep(1 * time.Second)
fmt.Println(“final value of x is”, x)
}

final value of x is 1000

Here the output is:-
final value of x is 1000

Lets see how we can resolve the same problem using channel:–

package main

import (
“fmt”
)

var x = 0

func myincrement(ch chan bool) {
x = x + 1
ch <- true
}

func main() {
ch := make(chan bool)
for i := 0; i < 1000; i++ {
go myincrement(ch)
<-ch
}
fmt.Println(“final value of x is”, x)
}

final value of x is 1000

Here the output is:–
final value of x is 1000

Mutex or Channels for race conditions:–
It depends on the situations. If Goroutines need to communicate with each other use channels, else we can use mutex. 1. Val Kerekes says:
2. web-dl says: