Open hic003cih opened 4 years ago
A “mutex” is a mutual exclusion lock. Mutexes allow us to lock our code so that only one goroutine can access that locked chunk of code at a time. package main
import ( "fmt" "runtime" "sync" )
func main() { fmt.Println("CPUs:", runtime.NumCPU()) fmt.Println("Goroutines:", runtime.NumGoroutine())
counter := 0
const gs = 100
var wg sync.WaitGroup
wg.Add(gs)
var mu sync.Mutex
for i := 0; i < gs; i++ {
go func() {
mu.Lock()
v := counter
// time.Sleep(time.Second)
runtime.Gosched()
v++
counter = v
mu.Unlock()
wg.Done()
}()
fmt.Println("Goroutines:", runtime.NumGoroutine())
}
wg.Wait()
fmt.Println("Goroutines:", runtime.NumGoroutine())
fmt.Println("count:", counter)
}
Atomic We can use package atomic to also prevent a race condition in our incrementer code.
package main
import (
"fmt"
"runtime"
"sync"
"sync/atomic"
)
func main() {
fmt.Println("CPUs:", runtime.NumCPU())
fmt.Println("Goroutines:", runtime.NumGoroutine())
var counter int64
const gs = 100
var wg sync.WaitGroup
wg.Add(gs)
for i := 0; i < gs; i++ {
go func() {
atomic.AddInt64(&counter, 1)
runtime.Gosched()
fmt.Println("Counter\t", atomic.LoadInt64(&counter))
wg.Done()
}()
fmt.Println("Goroutines:", runtime.NumGoroutine())
}
wg.Wait()
fmt.Println("Goroutines:", runtime.NumGoroutine())
fmt.Println("count:", counter)
}
Race condition Here is a picture of the race condition we are going to create. Race conditions are not good code. A race condition will give unpredictable results. We will see how to fix this race condition in the next video.