-
Notifications
You must be signed in to change notification settings - Fork 3
/
many2many.go
58 lines (50 loc) · 1.39 KB
/
many2many.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
// Stefan Nilsson 2013-03-13
// This is a testbed to help you understand channels better.
package main
import (
"fmt"
"math/rand"
"strconv"
"sync"
"time"
)
func main() {
// Use different random numbers each time this program is executed.
rand.Seed(time.Now().Unix())
const strings = 32
const producers = 4
const consumers = 2
before := time.Now()
ch := make(chan string)
wgp := new(sync.WaitGroup)
wgp.Add(producers)
for i := 0; i < producers; i++ {
go Produce("p"+strconv.Itoa(i), strings/producers, ch, wgp)
}
for i := 0; i < consumers; i++ {
go Consume("c"+strconv.Itoa(i), ch)
}
wgp.Wait() // Wait for all producers to finish.
close(ch)
fmt.Println("time:", time.Now().Sub(before))
}
// Produce sends n different strings on the channel and notifies wg when done.
func Produce(id string, n int, ch chan<- string, wg *sync.WaitGroup) {
for i := 0; i < n; i++ {
RandomSleep(100) // Simulate time to produce data.
ch <- id + ":" + strconv.Itoa(i)
}
wg.Done()
}
// Consume prints strings received from the channel until the channel is closed.
func Consume(id string, ch <-chan string) {
for s := range ch {
fmt.Println(id, "received", s)
RandomSleep(100) // Simulate time to consume data.
}
}
// RandomSleep waits for x ms, where x is a random number, 0 ≤ x < n,
// and then returns.
func RandomSleep(n int) {
time.Sleep(time.Duration(rand.Intn(n)) * time.Millisecond)
}