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)
}
}
并发