WaitGroup

var wg sync.WaitGroup

Image

Racing Condition

Occurs when order of execution is NOT guaranteed.

problem

https://go.dev/play/p/DxHz6ia14dt

package main

import (
    "fmt"
)

func main() {
    var data int

    go func() {
        data++
    }()

    fmt.Printf("the value of data is %v\n", data)
    fmt.Println("Done..")
}

solution

https://go.dev/play/p/l9CEVUT9xsc

package main

import (
    "fmt"
    "sync"
)

func main() {
    // program to print the value as 1
    // deterministically.
    var wg sync.WaitGroup
    var data int

    wg.Add(1)
    go func() {
        defer wg.Done()
        data++
    }()
    wg.Wait()
    fmt.Printf("the value of data is %v\n", data)

    fmt.Println("Done..")
}

Sequential Add vs Concurrency Add

Normal Add

func Add(numbers []int) int64 {
    var sum int64
    for _, n := range numbers {
        sum += int64(n)
    }
    return sum
}

Concurrency Add

// AddConcurrent - concurrent code to add numbers
func AddConcurrent(numbers []int) int64 {
    // Utilize all cores on machine
    numOfCores := runtime.NumCPU()
    runtime.GOMAXPROCS(numOfCores)

    var sum int64
    max := len(numbers)

    sizeOfParts := max / numOfCores

    var wg sync.WaitGroup

    for i := 0; i < numOfCores; i++ {

        // Divide the input into parts
        start := i * sizeOfParts
        end := start + sizeOfParts
        part := numbers[start:end]

        // Run computation for each part in seperate goroutine.
        wg.Add(1)
        go func(nums []int) {
            defer wg.Done()

            var partSum int64

            // Calculate sum for each part
            for _, n := range nums {
                partSum += int64(n)
            }

            // Add sum of each part to cummulative sum
            atomic.AddInt64(&sum, partSum)
        }(part)
    }

    wg.Wait()

    return sum
}

benchmark

go test -benchmem -run=none  -bench=. MyGoNote/concurrency/02_Goroutines/01_exercises/03_waitgroup/count/counting -v -count=1
goos: darwin
goarch: amd64
pkg: MyGoNote/concurrency/02_Goroutines/01_exercises/03_waitgroup/count/counting
cpu: Intel(R) Core(TM) i5-8259U CPU @ 2.30GHz
BenchmarkAdd
BenchmarkAdd-8                       156           7223807 ns/op          512840 B/op          0 allocs/op
BenchmarkAddConcurrent
BenchmarkAddConcurrent-8             480           2098310 ns/op          167298 B/op         18 allocs/op
PASS
ok      MyGoNote/concurrency/02_Goroutines/01_exercises/03_waitgroup/count/counting     6.251s
func BenchmarkAdd(b *testing.B) {
    numbers := GenerateNumbers(1e7)
    for i := 0; i < b.N; i++ {
        Add(numbers)
    }
}

func BenchmarkAddConcurrent(b *testing.B) {
    numbers := GenerateNumbers(1e7)
    for i := 0; i < b.N; i++ {
        AddConcurrent(numbers)
    }
}
© Kimi Tsai all right reserved.            Updated : 2023-07-12 09:04:54

results matching ""

    No results matching ""

    results matching ""

      No results matching ""