Channel
package main
import "fmt"
func main() {
ch := make(chan int)
go shower(ch)
for i := 0; i < 10; i++ {
ch <- i
}
}
func shower(c chan int) {
for {
j := <-c
fmt.Printf("%d\n", j)
}
}
/*以一般的方式開始,在第6 行建立了一個新的int 類型的channel。下一行調用
了shower 函數,用ch 變量做爲參數,這樣就能夠與其通信。而後進入for 循環
(第8-10 行),在循環中發送(經過<-)數字到函數(如今是goroutine)shower。
在函數shower 中等待(阻塞方式),直到接收到了數字(第15 行)。每一個收到的數
字都被打印(第16 行)出來,而後繼續第14 行開始的死循環。*/
2. 答案是
Listing 7.5. 添加額外的退出channel
package main
import "fmt"
func main() {
ch := make(chan int)
quit := make(chan bool)
go shower(ch, quit)
for i := 0; i < 10; i++ {
ch <- i
}
quit <- false // 或者是true,這沒啥關係
}
Chapter 7: 併發
func shower(c chan int, quit chan bool) {
for {
select {
case j := <-c:
fmt.Printf("%d\n", j)
case <-quit:
break
}
}
}
在第20 行從退出channel 讀取並丟棄該值。能夠使用q := <-quit,可是可能只須要
用這個變量一次——在Go 中是非法的。另外一種辦法,你可能已經想到了:_ = <-
quit。在Go 中這是合法的,可是第20 行的形式在Go 中更好。
A28. (7) 斐波那契II
1. 下面的程序使用channel 計算了斐波那契數列。
Listing 7.6. Go 的斐波那契函數
package main
import "fmt"
func dup3(in <-chan int) (<-chan int, <-chan int, <-chan int) {
a, b, c := make(chan int, 2), make(chan int, 2), make(chan int, 2)
go func() {
for {
x := <-in
a <- x
b <- x
c <- x
}
}(
return a, b, c
}
func fib() <-chan int {
x := make(chan int, 2)
a, b, out := dup3(x)
go func() {
x <- 0
x <- 1
<-a
for {
x <- <-a+<-b
}
}
return out
}
func main() {
x := fib()
for i := 0; i < 10; i++ {
fmt.Println(<-x)
}
}
併發