Skip to content

Instantly share code, notes, and snippets.

@shawnsmithdev
Last active October 11, 2015 10:47
Show Gist options
  • Save shawnsmithdev/44707d989495e9126a30 to your computer and use it in GitHub Desktop.
Save shawnsmithdev/44707d989495e9126a30 to your computer and use it in GitHub Desktop.
Effect of write lock attempt on read lock attempts
package main
import (
"fmt"
"sync"
"time"
)
type info struct {
step, thread uint64
val, prev, next string
}
func main() {
this := "A"
lock := &sync.RWMutex{}
start := time.Now()
report := make(chan *info)
go func() {
for reported := range report {
val := reported.val
if val == "" {
val = "?"
}
fmt.Printf("(%d-%d) %s @ %v %s|%s\n",
reported.step,
reported.thread,
val,
time.Since(start),
reported.prev,
reported.next)
}
}()
for i := uint64(0); i < 4; i++ {
go func(j uint64) {
report <- &info{step: 1, thread: j, next: "Rlock"}
lock.RLock()
defer lock.RUnlock()
report <- &info{step: 1, thread: j, val: this, prev: "Rlock", next: "Sleep 750ms"}
time.Sleep(750 * time.Millisecond)
report <- &info{step: 1, thread: j, val: this, prev: "Sleep 750ms", next: "defer RUnlock"}
}(i)
}
go func() {
report <- &info{step: 2, next: "Sleep 250ms"}
time.Sleep(time.Millisecond * 250)
report <- &info{step: 2, prev: "Sleep 250ms", next: "Lock"}
lock.Lock()
defer lock.Unlock()
report <- &info{step: 2, val: this, prev: "Lock", next: "Set B"}
this = "B"
report <- &info{step: 2, val: this, prev: "Set B", next: "defer Unlock"}
}()
go func() {
report <- &info{step: 3, next: "Sleep 500ms"}
time.Sleep(time.Millisecond * 500)
report <- &info{step: 3, prev: "Sleep 500ms", next: "RLock"}
lock.RLock()
defer lock.RUnlock()
report <- &info{step: 3, val: this, prev: "RLock", next: "Sleep 100ms"}
time.Sleep(time.Millisecond * 100)
report <- &info{step: 3, val: this, prev: "Sleep 100ms", next: "defer RUnlock"}
}()
time.Sleep(time.Second)
}
// (1-1) ? @ 166.255µs |Rlock
// (1-2) ? @ 270.705µs |Rlock
// (1-3) ? @ 283.906µs |Rlock
// (2-0) ? @ 295.047µs |Sleep 250ms
// (3-0) ? @ 306.541µs |Sleep 500ms
// (1-0) ? @ 317.837µs |Rlock
// (1-2) A @ 328.542µs Rlock|Sleep 750ms
// (1-1) A @ 373.706µs Rlock|Sleep 750ms
// (1-3) A @ 509.196µs Rlock|Sleep 750ms
// (1-0) A @ 557.335µs Rlock|Sleep 750ms
// (2-0) ? @ 250.930793ms Sleep 250ms|Lock
// (3-0) ? @ 506.0245ms Sleep 500ms|RLock
// (1-2) A @ 750.904071ms Sleep 750ms|defer RUnlock
// (1-3) A @ 750.997367ms Sleep 750ms|defer RUnlock
// (1-1) A @ 751.055258ms Sleep 750ms|defer RUnlock
// (1-0) A @ 751.131485ms Sleep 750ms|defer RUnlock
// (2-0) A @ 751.260427ms Lock|Set B
// (2-0) B @ 751.335704ms Set B|defer Unlock
// (3-0) B @ 751.43604ms RLock|Sleep 100ms
// (3-0) B @ 852.007714ms Sleep 100ms|defer RUnlock
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment