For the past few weeks I've been wrestling with one (not-so) simple question:
sync.Mutex
and, conversely, when is it best use a chan
?It seems that for a lot of problems either strategy is interchangeable with the other - and that's just the problem!
Take this video found in the Golang documentation. Below, I've taken the liberty to dictate the code in the playground and also translate it to a sync.Mutex
equivalent.
Notes:
chan
implementation does more work in the same time (reaches 12)*Playgrounds:
Ping/pong with chan
:
package main
import (
"fmt"
"time"
)
type Ball struct { hits int }
func main() {
table := make(chan *Ball)
go player("ping", table)
go player("pong", table)
table <- new(Ball)
time.Sleep(1 * time.Second)
<-table
}
func player(name string, table chan *Ball) {
for {
ball := <-table
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
table <- ball
}
}
Ping/pong with sync.Mutex
:
package main
import (
"fmt"
"time"
"sync"
)
type Ball struct { hits int }
var m = sync.Mutex{}
func main() {
ball := new(Ball)
go player("ping", ball)
go player("pong", ball)
time.Sleep(1 * time.Second)
}
func player(name string, ball *Ball) {
for {
m.Lock()
ball.hits++
fmt.Println(name, ball.hits)
time.Sleep(100 * time.Millisecond)
m.Unlock()
}
}
A Mutex is used to provide a locking mechanism to ensure that only one Goroutine is running the critical section of code at any point in time to prevent race conditions from happening.
For anyone who isn't familiar with Go, channels are a mechanism that allow goroutines (which are similar to threads) to pass data from one to another. That makes it easier to write thread-safe concurrent programs and prevent race conditions.
Common solutions are to use sync. Mutex , sync. RWMutex , or a mutex implemented with chan . Depending on how your application is structured, we can avoid locking with select .
The select statement lets a goroutine wait on multiple communication operations. A select blocks until one of its cases can run, then it executes that case. It chooses one at random if multiple are ready.
In Go, channels are fantastic, and you can use them to communicate between goroutines. However, you may want to use the sync.Mutex
in some circumstances for convenience.
These circumstances are like the following:
Here are three examples and explanations
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With