并发实践中的思考

2018-11-24  本文已影响0人  lizhuoming

为什么要写这篇博客

最近在学习Go并发的时候,想写一个并发的求斐波那契数的程序。期间遇到了一些坑,所以来记录一下自己的想法。

写并发程序中遇到的坑

并发1.0

使用最原始的方式,每次递归的时候,开一个协程去跑,将结果放入channel中。最终发现在求的数比较大的时候,并发比单线程还要慢。

并发2.0

于是我考虑应该是开的协程太多了,使用协程池来控制协程数量。代码如下:

func mutiExample(pool *tunny.Pool, ch chan int64, n int64) {
    var ans int64
    switch n {
    case 0:
        ans = 0
    case 1, 2:
        ans = 1
    default:
        res := make(chan int64, 2)

        a := func() {
            fmt.Println("start ", n-1)
            mutiExample(pool, res, n-1)
        }
        b := func() {
            fmt.Println("end ", n-2)
            mutiExample(pool, res, n-2)
        }
        go pool.Process(a)
        go pool.Process(b)
        ans = <-res + <-res
    }
    ch <- ans
}

func main() {
    start := time.Now()
    pool2 := tunny.NewCallback(3)
    ch := make(chan int64, 1)
    mutiExample(pool2, ch, 5)
    fmt.Println(<-ch, time.Since(start))
}

发现的问题

现象

分析

我们来通过一组结果分析它的执行过程

start  4
end  3
end  1
end  2
start  3

结论

如果要让程序不出现死锁,则需要限定协程池大小大于执行 n>2 的协程的总数量。
因为这种情况下程序无法直接返回,在等待接收数据。

自己的一些思考

总结

上一篇下一篇

猜你喜欢

热点阅读