摘自 从并发模型看 Go 的语言设计 | 腾讯技术工程,更新中…

Go 语言中channel<-左读右写

1. 阶乘计算

package main

import "fmt"

const limit = 5

func main() {
    fact := MakeFactFunc()

    for i := 0; i < limit; i++ {
        fmt.Println(fact(i))
    }
}

// 阶乘计算的实体
func FactCalc(in <-chan int, out chan<- int) {
    var subIn, subOut chan int
    for {
        n := <-in
        if n == 0 {
            out <- 1
        } else {
            if subIn == nil {
                subIn, subOut = make(chan int), make(chan int)
                go FactCalc(subIn, subOut)
            }
            subIn <- n - 1
            r := <-subOut
            out <- n * r
        }
    }
}

// 包装一个阶乘计算函数
func MakeFactFunc() func(int) int {
    in, out := make(chan int), make(chan int)
    go FactCalc(in, out)
    return func(x int) int {
        in <- x
        return <-out
    }
}

------
1
1
2
6
24

Process finished with exit code 0

2. 筛法求素数

package main

import "fmt"

func main() {
    primes := make(chan int)
    go PrimeSieve(primes)
    for i := 0; i < 5; i++ {
        fmt.Println(<-primes)
    }
}

func Counter(out chan<- int) {
    for i := 2; ; i++ {
        out <- i
    }
}

func PrimeFilter(prime int, in <-chan int, out chan<- int) {
    for {
        i := <-in
        if i%prime != 0 {
            out <- i
        }
    }
}

func PrimeSieve(out chan<- int) {
    c := make(chan int)
    go Counter(c)
    for {
        prime := <-c
        out <- prime
        newC := make(chan int)
        go PrimeFilter(prime, c, newC)
        c = newC
    }
}

------
2
3
5
7
11

Process finished with exit code 0

3. 信号量

4. 一个简单的服务模板

参考文章

  1. 从并发模型看 Go 的语言设计 | 腾讯技术工程