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…
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.
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:–
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.
faultless post
Great article! We are linking to this great article on our website. Keep up the good writing. Nannie Gawen Lewis