gobyexample/examples/state-goroutine/state-goroutine.go
2012-10-09 21:02:12 -07:00

92 lines
1.7 KiB
Go

package main
import "fmt"
import "time"
import "math/rand"
import "sync/atomic"
// 1 statefull go routine
// writers issue writes
// readers issue reads
// e.g. routing table
type readOp struct {
key int
resp chan int
}
type writeOp struct {
key int
val int
resp chan bool
}
func randKey() int {
return rand.Intn(10)
}
func randVal() int {
return rand.Intn(100)
}
func manageState(rs chan *readOp, ws chan *writeOp) {
data := make(map[int]int)
for {
select {
case read := <-rs:
read.resp <- data[read.key]
case write := <-ws:
data[write.key] = write.val
write.resp <- true
}
}
}
// Keep track of how many ops we do.
var opCount int64 = 0
// Generate random reads.
func generateReads(reads chan *readOp) {
for {
key := randKey()
read := &readOp{key: key, resp: make(chan int)}
reads <- read
<-read.resp
atomic.AddInt64(&opCount, 1)
}
}
// Generate random writes.
func generateWrites(writes chan *writeOp) {
for {
key := randKey()
val := randVal()
write := &writeOp{
key: key,
val: val,
resp: make(chan bool)}
writes <- write
<-write.resp
atomic.AddInt64(&opCount, 1)
}
}
func main() {
reads := make(chan *readOp)
writes := make(chan *writeOp)
go manageState(reads, writes)
for r := 0; r < 100; r++ {
go generateReads(reads)
}
for w := 0; w < 10; w++ {
go generateWrites(writes)
}
atomic.StoreInt64(&opCount, 0)
time.Sleep(time.Second)
finalOpCount := atomic.LoadInt64(&opCount)
fmt.Println(finalOpCount)
}