golang学习笔记——并发计算斐波纳契数

文章目录

  • 按顺序计算斐波纳契数
  • 并发计算斐波纳契数
  • 使用两个无缓冲 channel 的程序的第二个版本

按顺序计算斐波纳契数

golang学习笔记——将 channel 用作通信机制
golang学习笔记——并发计算斐波纳契数

package main

import (
    "fmt"
    "math/rand"
    "time"
)

func fib(number float64) float64 {
    x, y := 1.0, 1.0
    for 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 main

import (
    "fmt"
    "math/rand"
    "time"
)

func fib(number float64, ch chan string) {
    x, y := 1.0, 1.0
    for 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 := 15
    ch := 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 main

import (
    "fmt"
    "time"
)

var quit = make(chan bool)

func fib(c chan int) {
    x, y := 1, 1

    for {
        select {
            case c <- x:
                x, y = y, x+y
            case <-quit:
                fmt.Println("Done calculating Fibonacci!")
            return
        }
    }
}

func main() {
    start := time.Now()

    command := ""
    data := make(chan int)

    go fib(data)

    for {
        num := <-data
        fmt.Println(num)
        fmt.Scanf("%s", &command)
        if command == "quit" {
            quit <- true
            break
        }
    }

    time.Sleep(1 * time.Second)

    elapsed := time.Since(start)
    fmt.Printf("Done! It took %v seconds!\n", elapsed.Seconds())
}

你可能感兴趣的:(golang从入门到入门,golang,学习,笔记)