Skip to content

Instantly share code, notes, and snippets.

@plvhx
Last active January 1, 2022 06:38
Show Gist options
  • Save plvhx/8fba7e909e5cfeaa384dcb344c4be089 to your computer and use it in GitHub Desktop.
Save plvhx/8fba7e909e5cfeaa384dcb344c4be089 to your computer and use it in GitHub Desktop.
go concurrency 101
  • parameter supplied to the method 'Add' in the sync.WaitGroup struct must be equal to the current running goroutine. no more, no less.
    • if less than number of current running goroutine, it will leads to unexpected behavior.
    • if more than number of current running goroutine, it will leads to deadlock.
// dirty and simple :))
package main

import (
  "fmt"
  "sync"
  "time"
)

type Aggregator interface {
  Add(j *Job)
  Dispatch() 
}

type Job struct {
  text string
  lower int
  upper int
}

type Runner struct {
  jobs []*Job
  group *sync.WaitGroup
}

func (j *Job) outputText(group *sync.WaitGroup) {
  for j.lower < j.upper {
    time.Sleep(time.Millisecond)
    fmt.Println(j.text)
    j.lower++
  }

  group.Done()
}

func (r *Runner) Add(j *Job) {
  r.jobs = append(r.jobs, j)
}

func (r *Runner) Dispatch() {
  for _, v := range r.jobs {
    go v.outputText(r.group)
  }

  r.group.Add(len(r.jobs))
  r.group.Wait()
}

func main() {
  r := Runner{jobs: make([]*Job, 0), group: new(sync.WaitGroup)}

  r.Add(&Job{text: "hello", lower: 0, upper: 3})
  r.Add(&Job{text: "world", lower: 0, upper: 5})
  r.Add(&Job{text: "this is a shit", lower: 0, upper: 2})
  r.Dispatch()
}
  • if you don't ever yield to the main thread, your goroutines will perform in unexpected ways (or won't perform at all).
  • if you call runtime.GOMAXPROCS with value 0, it doesn't change / alter the number of CPU cores that will be used to run any number of existing goroutine.
  • runtime.GOMAXPROCS value can read value from environment variable too. Look at the example below:
package main

import (
  "fmt"
  "runtime"
)

func main() {
  // get current number of GOMAXPROCS
  fmt.Printf("GOMAXPROCS: %v\n", runtime.GOMAXPROCS(0))
}
# read from environment variable
shell~$ GOMAXPROCS=2 go run main.go
2
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment