1 package main
2
3 import ( "fmt"; "os"; "flag"; "strconv"; "rand" )
4
5
6
7
8
9
10
11
12
13 func printer(done chan int) chan int {
14 ch := make(chan int)
15
16 go func() {
17 for {
18 i := <- ch
19
20 if i == 0 && closed(ch) {
21 close(done)
22 break
23 }
24
25 fmt.Printf("%d\n", i)
26 }
27 }()
28
29 return ch
30 }
31
32
33
34
35
36
37
38
39
40 func adder(next chan int, n int) chan int {
41 ch := make(chan int)
42
43 go func() {
44 for {
45 i := <- ch
46
47 if i == 0 && closed(ch) {
48 close(next)
49 break
50 }
51
52 next <- i + n
53 }
54 }()
55
56 return ch
57 }
58
59
60
61
62 func main() {
63 if flag.NArg() != 1 {
64 os.Stderr.WriteString("Usage: counter <N>\n")
65 os.Exit(1)
66 }
67
68 n, err := strconv.Atoi(flag.Arg(0))
69
70 if err != nil {
71 fmt.Fprintf(os.Stderr, "The argument must be a number (%v)\n", err)
72 os.Exit(1)
73 }
74
75
76
77
78 done := make(chan int)
79 ch := printer(done)
80
81 for i := n; i > 0; i-- {
82 ch = adder(ch, i)
83 }
84
85
86
87
88 for i := 0; i < 10000; i++ {
89 r := rand.Intn(20) + 1
90 ch <- r
91 }
92
93
94 close(ch)
95 <- done
96 }