fmt.Println("You're boring. I'm leaving.")
}
+
func main2() {
joe := boring("Joe")
ann := boring("Ann")
fmt.Println("You're both boring. I'm leaving.")
}
+
func fanIn(input1, input2 <- chan string) <-chan string {
c := make(chan string)
go func() { for { c <- <-input1 } }()
return c
}
+func fanIns(input1, input2 <- chan string) <-chan string {
+ c := make(chan string)
+ go func() {
+ for {
+ select {
+ case s := <- input1: c <- s
+ case s := <- input2: c <- s
+ }
+ }
+ }()
+ return c
+}
+
func main3() {
c := fanIn(boring("Joe"), boring("Ann"))
for i := 0; i < 10; i++ {
fmt.Println("You're boring. I'm leaving.")
}
+
+type Message struct {
+ str string
+ wait chan bool
+}
+
+func boring4(msg string) <- chan Message {
+ c := make(chan Message)
+ // Buffering removes a block in main4() loop, when 'true' is send to
+ // 'wait' channel. Thus, next message will first arrive from the guy, who
+ // slept less. Without buffering, main4() will wait until slower guy
+ // awakes from 'Sleep' and read 'wait' channel, so the Ann will almost
+ // always be the first one.
+ waitForIt := make(chan bool, 2)
+ go func() {
+ for i := 0; ; i++ {
+ r := rand.Intn(1e3)
+ c <- Message{ fmt.Sprintf("%s %d (%d)", msg, i, r), waitForIt }
+ time.Sleep(time.Duration(r) * time.Millisecond)
+ <-waitForIt
+ }
+ }()
+ return c
+}
+
+func fanIn4(input1, input2 <- chan Message) <-chan Message {
+ c := make(chan Message)
+ go func() { for { c <- <-input1 } }()
+ go func() { for { c <- <-input2 } }()
+ return c
+}
+
+func fanIn4s(input1, input2 <- chan Message) <-chan Message {
+ c := make(chan Message)
+ go func() {
+ for {
+ select {
+ case s := <- input1: c <- s
+ case s := <- input2: c <- s
+ }
+ }
+ }()
+ return c
+}
+
+func main4() {
+ c := fanIn4s(boring4("Joe"), boring4("Ann"))
+ for i := 0; i < 5; i++ {
+ msg1 := <-c; fmt.Println(msg1.str)
+ msg2 := <-c; fmt.Println(msg2.str)
+ msg1.wait <- true
+ msg2.wait <- true
+ }
+ fmt.Println("You're boring. I'm leaving.")
+}
+
+// This is the same as main3(). 'wait' channel has no sense here, because
+// after reading a message, i immediatelly send "go on" over 'wait' channel to
+// the guy, who have spoken right now.
+func main41() {
+ c := fanIn4s(boring4("Joe"), boring4("Ann"))
+ for i := 0; i < 10; i++ {
+ msg := <-c; fmt.Println(msg.str)
+ msg.wait <- true
+ }
+ fmt.Println("You're boring. I'm leaving.")
+}
+
func main() {
rand.Seed(time.Now().Unix())
- main3()
+ main4()
}