Skip to content

Instantly share code, notes, and snippets.

@thriqon

thriqon/locks.go Secret

Created April 12, 2016 07:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thriqon/f94c10a45b7e0bf656781b0f4a07292a to your computer and use it in GitHub Desktop.
Save thriqon/f94c10a45b7e0bf656781b0f4a07292a to your computer and use it in GitHub Desktop.
Demonstrating Single-Variable-Locks are not enough...
package main
import (
"log"
"sync"
)
var (
wg sync.WaitGroup
am sync.Mutex
a int
bm sync.Mutex
b int
)
func withdraw(v int) {
am.Lock()
al := a
am.Unlock()
am.Lock()
a = al - v
am.Unlock()
bm.Lock()
bl := b
bm.Unlock()
bm.Lock()
b = bl + v
bm.Unlock()
wg.Done()
}
func deposit(v int) {
bm.Lock()
bl := b
bm.Unlock()
bm.Lock()
b = bl - v
bm.Unlock()
am.Lock()
al := a
am.Unlock()
am.Lock()
a = al + v
am.Unlock()
wg.Done()
}
func main() {
counter := 0
for {
wg.Add(2)
go withdraw(10)
go deposit(5)
wg.Wait()
counter++
if a+b != 0 {
log.Fatalf("Invariant failed in case %v with a+b == %v+%v", counter, a, b)
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment