Golang synchronization

From wikinotes

Synchronization tools are used to synchronize multiple concurrent codepaths so that your program can continue synchronously.

Documentation

sync docs https://pkg.go.dev/sync

Mutexes

Mutex

A lock used to synchronize threads. No wait-time is specified, you are responsible for re-trying the lock if desired.

var lock = Mutex{}

lock.Lock()
lock.Unlock()
lock.TryLock()  // discouraged

RWMutex

Variation of a mutex where:

  • any number of items can acquire a lock for reading
  • only one item can acquire lock for writing
  • you cannot write while any other lock is reading
import "sync"

var lock = RWMutex{}

// lock/unlock for reading
lock.RLock()
lock.RUnlock()

// lock/unlock for writing
lock.Lock()
lock.Unlock()

It would be sensible to unlcok in deferred functions.

WaitGroups

WaitGroups are global threadsafe counters that are incremented/decremented.

wg = sync.WaitGroup{}

wg.Add(3)  // add 3x increments to countdown
wg.Done()  // decrement waitgroup by one
wg.Wait()  // wait for waitgroup to reach 0
// wait-groups are threadsafe proxy objects, intended to be globally accessible
var wg = sync.WaitGroup{}

func printHi() {
    fmt.Println("hi")
    wg.Done()
}

func main() {
    wg.Add(3)
    for i=0; i<3; i++ {
        go printHi()
    }
    wg.Wait()
    fmt.Println("bye")
}