Skip to content

Instantly share code, notes, and snippets.

@sescobb27
Created April 4, 2015 07:44
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 sescobb27/1cfd35c4c7f84f00eed3 to your computer and use it in GitHub Desktop.
Save sescobb27/1cfd35c4c7f84f00eed3 to your computer and use it in GitHub Desktop.
Mutex readers-writers
package main
import (
"log"
"os"
"rand"
"sync"
"time"
)
// thread safe output
var fmt = log.New(os.Stdout, "", log.Lmicroseconds)
// type representing shared resource. contents could be anything
type resource struct {
string
}
// struct wraps pointer to resource with embedded RWMutex, thus
// acquiring RWMutex methods
type access struct {
sync.RWMutex
res *resource
}
func main() {
acc := &access{res: &resource{"zero"}}
fmt.Println("Initial value:", acc.res.string)
gr := new(sync.WaitGroup)
gr.Add(5) // three readers and two writers
go reader("A", acc, gr)
go reader("B", acc, gr)
go reader("C", acc, gr)
go writer("X", acc, gr)
go writer("Y", acc, gr)
gr.Wait()
fmt.Println("Final value:", acc.res.string)
}
// reader reads three times at about .1 second intervals, taking
// .02 second to perform the read
func reader(name string, acc *access, gr *sync.WaitGroup) {
rn := rand.New(rand.NewSource(time.Nanoseconds()))
for i := 0; i < 3; i++ {
time.Sleep(8e7 + rn.Int63n(4e7))
fmt.Println("reader", name, "ready to read")
acc.RLock()
fmt.Println("reader", name, "reading")
time.Sleep(2e7)
msg := acc.res.string
acc.RUnlock()
fmt.Println("reader", name, "read:", msg)
}
gr.Done()
}
// writer writes twice
func writer(name string, acc *access, gr *sync.WaitGroup) {
rn := rand.New(rand.NewSource(time.Nanoseconds()))
claim := []string{"once", "again"}
for i := 0; i < 2; i++ {
time.Sleep(8e7 + rn.Int63n(4e7))
msg := name + " was here " + claim[i]
fmt.Println("writer", name, "ready to write")
acc.Lock()
fmt.Println("writer", name, "writing:", msg)
time.Sleep(2e7)
acc.res.string = msg
acc.Unlock()
fmt.Println("writer", name, "done")
}
gr.Done()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment