A Mutex is a method used as a locking mechanism to ensure that only one Goroutine is accessing the critical section of code at any point of time. This is done to prevent race conditions from happening. Sync package contains the Mutex. Two methods defined on Mutex
Any code present between a call to Lock and Unlock will be executed by only one Goroutine.
mutex.Lock() x = x + 1 // this statement be executed // by only one Goroutine // at any point of time mutex.Unlock()
If one Goroutine already has the lock and if a new Goroutine is trying to get the lock, then the new Goroutine will be stopped until the mutex is unlocked. To understand this concept, let’s first understand a program having race conditions.
Program with Race Condition
Here is an example of a program which encounters race condition
Explanation: In the program above, the worker function in line no. 12 increments the value of GFG by 1 and then calls Done() on the WaitGroup to inform its completion. The worker function is called 1000 times. Each of these Goroutines run simultaneously and race condition occurs when trying to increment GFG in line no. 13 as multiple Goroutines try to access the value of GFG concurrently. Running the same program multiple times gives different outputs each time because of the race condition.
Remember one thing, if you will check the output of the above program using the online compiler, you might get the same output every time(means no race condition) due to the deterministic nature. So use the local compiler like Visual Studio or CMD to see the results.
Solving the Above Problem Using Mutex
Here is an example of a program which how race condition is fixed.
Value of x 1000
Explanation: Mutex is a struct type and variable m of type Mutex is created in line no. 31. The worker function is changed so that the code which increments GFG in line no. 18 between m.Lock() and m.Unlock(). Now only one Goroutine is allowed to execute this piece of code at any point of time and thus race condition is dealt with.
The address of mutex has to be passed in line no. 37. If the mutex is passed by value instead then each Goroutine will have its own copy of the mutex and the race condition will still persist.