What is a Mutex in Golang?

Search for a command to run...

No comments yet. Be the first to comment.
C# is one of my favorite languages; if you're building Windows apps, you're probably better off with C#, but I'm kind of rusty, and WinForms is old school now, so I've no choice but to use WPF 😔. The

I have been thinking about where we are at with AI in 2026; I think most models have now reached their intelligence ceiling. They’ll get incrementally better over time, sure, but there’s a big difference between 10% to 80% and 80% to 100%. In most te...

Django is one of my favourite frameworks; however, the official docs are not always the best resource to look up information when you are in a hurry. Don't get me wrong, the official docs are very use

While the whole YouTube influencer space goes crazy about Gemini 3, I’m not so impressed. Don’t get me wrong, Gemini models are fantastic! And the V3 iteration is undoubtedly cool and capable. I’ve briefly run some tests (not benchmarks but actual re...

I’m learning Next.js; I know React or kinda know React since I started building React apps in 2018 or thereabout, and then stopped using it for several years. Shew! A lot has changed: Server actions, Zod, and just the whole ecosystem generally. This ...

When you build Golang programs, you will almost always find a use for Goroutines.
Goroutines are powerful and generally easy to use, however, if you need to modify some piece of data that is shared between Goroutines - then you may run into some trouble with data integrity.
In this article, we will look at what is a "Mutex" and how to use it.
In Golang; a Goroutine is essentially a function that is put in a background queue and executed concurrently whenever resources are available.
package main
import (
"fmt"
"sync"
)
var NUM_PROCESSED = 0
func countNumProcessed(wg *sync.WaitGroup) {
defer wg.Done()
NUM_PROCESSED++
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 500; i++ {
wg.Add(1)
go countNumProcessed(&wg)
}
wg.Wait()
fmt.Println(NUM_PROCESSED)
}
If we remove the "go" keyword, each function call to "countNumProcessed" will block the loop and wait for this function to finish before continuing with the loop.
When you use the "go" keyword, these functions will be run concurrently. Which then makes it possible for 2 or more functions to modify the variable at the same time.
If you run this code a few times - you will notice that the total count fluctuates.
This is because each Goroutine, for a few nanoseconds copies the value of "NUM_PROCESSED" in memory to increment it and then update the variable.
If two (or more) Goroutines copy the value around the same time, they will not be aware of updates made by other Goroutines.
For example: let's assume the value was "200"; each of the two Goroutines will add "1" i.e. "201". Thus the value for "NUM_PROCESSED" will become "201" instead of "202".
This is where a Mutex comes in handy. A Mutex will create a "lock" in the process - so that only one Goroutine can update "NUM_PROCESSED" at a time.

The other Goroutines will then be paused until the lock is released. This is very similar to a queue - when each Goroutine releases the lock, the next one acquires a new lock and the process continues until all the queued Goroutines finish updating "NUM_PROCESSED".
We can modify the above code to introduce a Mutex as follows:
package main
import (
"fmt"
"sync"
)
var NUM_PROCESSED = 0
var MUTEX sync.Mutex
func countNumProcessed(wg *sync.WaitGroup) {
defer wg.Done()
MUTEX.Lock()
NUM_PROCESSED++
MUTEX.Unlock()
}
func main() {
var wg sync.WaitGroup
for i := 0; i < 500; i++ {
wg.Add(1)
go countNumProcessed(&wg)
}
wg.Wait()
fmt.Println(NUM_PROCESSED)
}
You will notice with the above code, that no matter how many times you run this function, it will always print "500". This is precisely the same amount of goroutines created in the for loop.