Skip to content

Instantly share code, notes, and snippets.

@cofyc
Last active March 23, 2017 15:39
Show Gist options
  • Save cofyc/4df7122f150368e40874c3248b472c74 to your computer and use it in GitHub Desktop.
Save cofyc/4df7122f150368e40874c3248b472c74 to your computer and use it in GitHub Desktop.
sync.RWMutex
package main
import (
"flag"
"fmt"
"sync"
"time"
)
var (
writeBeforeRead bool
)
func init() {
flag.BoolVar(&writeBeforeRead, "write-before-read", false, "")
}
func main() {
flag.Parse()
var m sync.RWMutex
readlocked := make(chan int)
var wg sync.WaitGroup
// hold read lock first
wg.Add(1)
go func() {
defer wg.Done()
m.RLock()
fmt.Printf("goroutine 1: read locked\n")
close(readlocked)
time.Sleep(3 * time.Second)
m.RUnlock()
fmt.Printf("goroutine 1: read unlocked\n")
}()
// this want to write
wg.Add(1)
go func() {
defer wg.Done()
<-readlocked
if !writeBeforeRead {
// wait a while, let reader to get lock first
time.Sleep(1 * time.Second)
}
fmt.Printf("goroutine 2: trying to lock write\n")
m.Lock()
fmt.Printf("goroutine 2: write locked\n")
time.Sleep(3 * time.Second)
m.Unlock()
fmt.Printf("goroutine 2: write unlocked\n")
}()
// this want to read
wg.Add(1)
go func() {
defer wg.Done()
<-readlocked
if writeBeforeRead {
// wait a while, let writer to get lock first
time.Sleep(1 * time.Second)
}
fmt.Printf("goroutine 3: trying to lock read\n")
m.RLock()
fmt.Printf("goroutine 3: read locked\n")
time.Sleep(3 * time.Second)
m.RUnlock()
fmt.Printf("goroutine 3: read unlocked\n")
}()
wg.Wait()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment