fmt.Println("You're boring. I'm leaving.")
}
+func main5() {
+ c := boring("Joe")
+ for {
+ select {
+ case s := <-c:
+ fmt.Println(s)
+ case <-time.After(2200 * time.Millisecond):
+ fmt.Println("You're too slow.")
+ return
+ }
+ }
+}
+
+func main6() {
+ c := boring("Joe")
+ timeout := time.After(7 * time.Second)
+ for {
+ select {
+ case s := <-c:
+ fmt.Println(s)
+ case <-timeout:
+ fmt.Println("You talk too much.")
+ return
+ }
+ }
+}
+
+func boring7(msg string, quit chan bool) <- chan string {
+ c := make(chan string)
+ go func() {
+ for i := 0; ; i++ {
+ r := rand.Intn(3e3)
+ select {
+ case c <- fmt.Sprintf("%s %d (%d)", msg, i, r):
+ case <-quit:
+ return
+ }
+ time.Sleep(time.Duration(r) * time.Millisecond)
+ }
+ }()
+ return c
+}
+
+func main7() {
+ quit := make(chan bool)
+ c := boring7("Joe", quit)
+ r := rand.Intn(10)
+ fmt.Printf("Expecting %v values\n", r + 1)
+ for i := r; i >= 0; i-- {
+ fmt.Printf("%q\n", <-c)
+ }
+ quit <-true
+ fmt.Println("You're boring. I'm leaving.")
+}
+
+func cleanup() {
+ fmt.Println("Cleanup")
+}
+
+func boring8(msg string, quit chan string) <- chan string {
+ c := make(chan string)
+ go func() {
+ for i := 0; ; i++ {
+ r := rand.Intn(3e3)
+ select {
+ case c <- fmt.Sprintf("%s %d (%d)", msg, i, r):
+ case <-quit:
+ cleanup()
+ quit <- "See you!"
+ return
+ }
+ time.Sleep(time.Duration(r) * time.Millisecond)
+ }
+ }()
+ return c
+}
+
+func main8() {
+ quit := make(chan string)
+ c := boring8("Joe", quit)
+ r := rand.Intn(10)
+ fmt.Printf("Expecting %v values\n", r + 1)
+ for i := r; i >= 0; i-- {
+ fmt.Printf("%q\n", <-c)
+ }
+ quit <- "Bye!"
+ fmt.Printf("Joe says: %q\n", <-quit)
+}
+
+func f(left, right chan int) {
+ left <- 1 + <-right
+}
+
+func main9() {
+ const n = 10000
+ leftmost := make(chan int)
+ right := leftmost
+ left := leftmost
+ for i := 0; i < n; i++ {
+ right = make(chan int)
+ go f(left, right)
+ left = right
+ }
+ go func(c chan int) { c <- 1 }(right)
+ fmt.Println(<-leftmost)
+}
+
+// Build a chain in reverse direction.
+func main91() {
+ const n = 10000
+ rightmost := make(chan int)
+ right := rightmost
+ var left chan int
+ for i := 0; i < n; i++ {
+ left = make(chan int)
+ go f(left, right)
+ right = left
+ }
+ go func(c chan int) { c <- 1 }(rightmost)
+ fmt.Println(<-left)
+}
+
func main() {
rand.Seed(time.Now().Unix())
- main4()
+ main9()
}