1
0
mirror of https://github.com/golang/go synced 2024-11-24 22:57:57 -07:00

runtime: add test for multiple concurrent channel consumers

There was a time (in the past) when this wasn't robust.

R=rsc, dvyukov
CC=golang-dev
https://golang.org/cl/4965058
This commit is contained in:
Christopher Wedgwood 2011-09-05 07:40:50 -04:00 committed by Russ Cox
parent 740805fdb1
commit 6cf61bb5b9

View File

@ -59,6 +59,57 @@ func TestPseudoRandomSend(t *testing.T) {
t.Errorf("Want pseudo random, got %d zeros and %d ones", n0, n1) t.Errorf("Want pseudo random, got %d zeros and %d ones", n0, n1)
} }
func TestMultiConsumer(t *testing.T) {
const nwork = 23
const niter = 271828
pn := []int{2, 3, 7, 11, 13, 17, 19, 23, 27, 31}
q := make(chan int, nwork*3)
r := make(chan int, nwork*3)
// workers
var wg sync.WaitGroup
for i := 0; i < nwork; i++ {
wg.Add(1)
go func(w int) {
for v := range q {
// mess with the fifo-ish nature of range
if pn[w%len(pn)] == v {
runtime.Gosched()
}
r <- v
}
wg.Done()
}(i)
}
// feeder & closer
expect := 0
go func() {
for i := 0; i < niter; i++ {
v := pn[i%len(pn)]
expect += v
q <- v
}
close(q) // no more work
wg.Wait() // workers done
close(r) // ... so there can be no more results
}()
// consume & check
n := 0
s := 0
for v := range r {
n++
s += v
}
if n != niter || s != expect {
t.Errorf("Expected sum %d (got %d) from %d iter (saw %d)",
expect, s, niter, n)
}
}
func BenchmarkSelectUncontended(b *testing.B) { func BenchmarkSelectUncontended(b *testing.B) {
const CallsPerSched = 1000 const CallsPerSched = 1000
procs := runtime.GOMAXPROCS(-1) procs := runtime.GOMAXPROCS(-1)