DEV Community

Cover image for Goroutine Race Condition
Muhammad Saiful
Muhammad Saiful

Posted on • Edited on

Goroutine Race Condition

What is race conditions ?...

A race condition is a condition when more than one goroutine accesses the same data at the same time. Cause of that the data gets messed up, it's common case in concurrency programming.

How to solve it ?....

Golang provides a package called sync.mutex, when the race condition occurs, only one goroutine can access the data, with mutex all goroutines can access data, how it works ? mutex can control data flow using lock and unlock function

Let's code

A.Validate Race Condition

1.Initial variable with a function to increment the value

type counter struct {
    number int
}

func (value *counter) Add(param int) {
    value.number += param
}

Enter fullscreen mode Exit fullscreen mode

2.Run the counter function using goroutines and sync.WaitGroup


import (
    "fmt"
    "sync"
)

func main() {
    var counter counter
    wg := new(sync.WaitGroup)
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            for i := 0; i < 100; i++ {
                counter.Add(1)
            }
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(counter.number)
}
Enter fullscreen mode Exit fullscreen mode

Full code

package main

import (
    "fmt"
    "sync"
)

type counter struct {
    number int
}

func (value *counter) Add(param int) {
    value.number += param
}

func main() {
    var counter counter
    wg := new(sync.WaitGroup)
    for i := 0; i < 100; i++ {
        wg.Add(1)
        go func() {
            for i := 0; i < 100; i++ {
                counter.Add(1)
            }
            wg.Done()
        }()
    }
    wg.Wait()
    fmt.Println(counter.number)
}
Enter fullscreen mode Exit fullscreen mode

run the code using this command

go run -race main.go

add -race flag is to detect race condition in our goroutine, and the result is:

Image description

race condition is detected how we can solve this problem..... ?

Let's Solve

In this case using sync.mutex package is the best solution, cause we can lock data when task is begin and unlock data when task is done.

B.Solve Race Condition

1.Add sync.mutex in counter struct

type counter struct {
    number int
    sync.Mutex
}
Enter fullscreen mode Exit fullscreen mode

2.Lock & Unlock data

func (value *counter) Add(param int) {
    value.Lock()
    value.number += param
    value.Unlock()
}
Enter fullscreen mode Exit fullscreen mode

3.Run Code

No race conditions will be detected and our problem is solved

go run -race main.go

result is 100000

Conclusion
sync.Mutex is one of thread safe type, using this package makes our goroutines safer and far from race conditions

don't panic & stay safe, thanks

Top comments (0)