hic003cih / Golang

0 stars 0 forks source link

2019.10.16 #11

Open hic003cih opened 4 years ago

hic003cih commented 4 years ago

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.

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)

    for i := 0; i < gs; i++ {
        go func() {
            v := counter
            // time.Sleep(time.Second)
            runtime.Gosched()
            v++
            counter = v
            wg.Done()
        }()
        fmt.Println("Goroutines:", runtime.NumGoroutine())
    }
    wg.Wait()
    fmt.Println("Goroutines:", runtime.NumGoroutine())
    fmt.Println("count:", counter)
}
hic003cih commented 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)

}

hic003cih commented 4 years ago

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)
}