Skip to content

Instantly share code, notes, and snippets.

@cauli
Last active August 29, 2017 17:28
Show Gist options
  • Save cauli/e267e86f9f83a1fae7b15ccf897724b2 to your computer and use it in GitHub Desktop.
Save cauli/e267e86f9f83a1fae7b15ccf897724b2 to your computer and use it in GitHub Desktop.
Example explaining RWMutex composition on a struct
package main
import (
"fmt"
"sync"
"net/url"
"math/rand"
"strconv"
"time"
)
type MutexHolder struct {
sync.RWMutex
Fields url.Values
}
func main() {
start := time.Now()
var wg sync.WaitGroup
wait := 3 * time.Second
for i:=0; i<5; i++ {
m := MutexHolder {
Fields: map[string][]string{"key": {"value", "value2"}},
}
wg.Add(3)
go printByReference(&m, i, wait, &wg)
go printByReference(&m, i, wait, &wg)
go printByReference(&m, i, wait, &wg)
// Goroutines will finish in `wait * count(printByReference calls)` seconds because RWMutex is shared
//wg.Add(3)
//go printByValue(m, i, wait, &wg)
//go printByValue(m, i, wait, &wg)
//go printByValue(m, i, wait, &wg)
// Goroutines will finish in `wait` seconds because RWMutex is shared
}
wg.Wait()
fmt.Println("Took: ", time.Since(start))
}
func printByReference(mh *MutexHolder, i int, wait time.Duration, wg *sync.WaitGroup) {
defer wg.Done()
mh.Lock()
time.Sleep(wait)
mh.Fields.Add("RandInt", strconv.Itoa(rand.Intn(100)))
mh.Fields.Add("MyAddress", fmt.Sprintf("%p", &mh))
mh.Fields.Set("LoopIndex", strconv.Itoa(i))
fmt.Println(mh)
mh.Unlock()
}
func printByValue(mh MutexHolder, i int, wait time.Duration, wg *sync.WaitGroup) {
defer wg.Done()
mh.Lock()
time.Sleep(wait)
mh.Fields.Add("RandInt", strconv.Itoa(rand.Intn(100)))
mh.Fields.Add("MyAddress", fmt.Sprintf("%p", &mh))
mh.Fields.Set("LoopIndex", strconv.Itoa(i))
fmt.Println(mh)
mh.Unlock()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment