文章目录
- 按顺序计算斐波纳契数
- 并发计算斐波纳契数
- 使用两个无缓冲 channel 的程序的第二个版本
按顺序计算斐波纳契数
golang学习笔记——将 channel 用作通信机制
golang学习笔记——并发计算斐波纳契数
package mainimport ("fmt""math/rand""time"
)func fib(number float64) float64 {x, y := 1.0, 1.0for i := 0; i < int(number); i++ {x, y = y, x+y}r := rand.Intn(3)time.Sleep(time.Duration(r) * time.Second)return x
}func main() {start := time.Now()for i := 1; i < 15; i++ {n := fib(float64(i))fmt.Printf("Fib(%v): %v\n", i, n)}elapsed := time.Since(start)fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}
输出
1
1
2
3
5
8
13
quit
Done calculating Fibonacci!
Done! It took 12.043196415 seconds!
并发计算斐波纳契数
实现并发的改进版本。完成此操作需要几秒钟的时间(不超过 15 秒),就像现在这样。 应使用有缓冲 channel。
package mainimport ("fmt""math/rand""time"
)func fib(number float64, ch chan string) {x, y := 1.0, 1.0for i := 0; i < int(number); i++ {x, y = y, x+y}r := rand.Intn(3)time.Sleep(time.Duration(r) * time.Second)ch <- fmt.Sprintf("Fib(%v): %v\n", number, x)
}func main() {start := time.Now()size := 15ch := make(chan string, size)for i := 0; i < size; i++ {go fib(float64(i), ch)}for i := 0; i < size; i++ {fmt.Printf(<-ch)}elapsed := time.Since(start)fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}
输出
Fib(0): 1
Fib(3): 3
Fib(1): 1
Fib(12): 233
Fib(6): 13
Fib(7): 21
Fib(5): 8
Fib(8): 34
Fib(11): 144
Fib(10): 89
Fib(2): 2
Fib(9): 55
Fib(14): 610
Fib(4): 5
Fib(13): 377
Done! It took 2.0160237 seconds!
使用两个无缓冲 channel 的程序的第二个版本
使用两个无缓冲 channel:一个用于计算斐波纳契数,另一个用于等待用户的“退出”消息。 你需要使用 select
语句。
package mainimport ("fmt""time"
)var quit = make(chan bool)func fib(c chan int) {x, y := 1, 1for {select {case c <- x:x, y = y, x+ycase <-quit:fmt.Println("Done calculating Fibonacci!")return}}
}func main() {start := time.Now()command := ""data := make(chan int)go fib(data)for {num := <-datafmt.Println(num)fmt.Scanf("%s", &command)if command == "quit" {quit <- truebreak}}time.Sleep(1 * time.Second)elapsed := time.Since(start)fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}