Mutex
- 互斥鎖的代價比原子操作大, 可通過原子檢查狀態提高性能
type Once struct{ m Mutx done uint32 } func (o *Once) Do(f func()){ if atomic.LoadUint32(&o.done)==1{ return } } - Mutex is used guards access to shared resoures.
- It is developers convention to call
Lock()to access shared memory and callUnlock()when done. - The critical section represents the bottleneck between the goroutines.
When to use channels and when to use mutex

| Channels | Mutex |
|---|---|
|
|
|
Mutex
- Used for protect shared resources.
- sync.Mutex - Provide exclusive access to a shared resource.
| ```go mu.Lock() balance += amount mu.Unlock() ``` | ```go mu.Lock() defer mu.Unlock() balance -= amount ``` |
Exercises
https://go.dev/play/p/mqjVI-1aZRd
package main
import (
"fmt"
"runtime"
"sync"
)
func main() {
runtime.GOMAXPROCS(4)
var balance int
var wg sync.WaitGroup
var mu sync.Mutex
deposit := func(amount int) {
mu.Lock()
balance += amount
mu.Unlock()
}
withdrawal := func(amount int) {
mu.Lock()
defer mu.Unlock()
balance -= amount
}
// we are making 100 times deposits of $1
// and 100 times withdrawal of $1, concurrently.
// run the program and check result.
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
deposit(1)
}()
}
wg.Add(100)
for i := 0; i < 100; i++ {
go func() {
defer wg.Done()
withdrawal(1)
}()
}
wg.Wait()
fmt.Println(balance)
}