menu arrow_back 湛蓝安全空间 |狂野湛蓝,暴躁每天 chevron_right All_wiki chevron_right the-way-to-go_ZH_CN chevron_right eBook chevron_right 14.9.md
  • home 首页
  • brightness_4 暗黑模式
  • cloud
    xLIYhHS7e34ez7Ma
    cloud
    湛蓝安全
    code
    Github
    14.9.md
    2.31 KB / 2024-07-16 23:14:29
        # 14.9 实现 Futures 模式
    
    所谓 Futures 就是指:有时候在你使用某一个值之前需要先对其进行计算。这种情况下,你就可以在另一个处理器上进行该值的计算,到使用时,该值就已经计算完毕了。
    
    Futures 模式通过闭包和通道可以很容易实现,类似于生成器,不同地方在于 Futures 需要返回一个值。
    
    参考条目文献给出了一个很精彩的例子:假设我们有一个矩阵类型,我们需要计算两个矩阵 A 和 B 乘积的逆,首先我们通过函数 `Inverse(M)` 分别对其进行求逆运算,再将结果相乘。如下函数 `InverseProduct()` 实现了如上过程:
    
    ```go
    func InverseProduct(a Matrix, b Matrix) {
        a_inv := Inverse(a)
        b_inv := Inverse(b)
        return Product(a_inv, b_inv)
    }
    ```
    
    在这个例子中,`a` 和 `b` 的求逆矩阵需要先被计算。那么为什么在计算 `b` 的逆矩阵时,需要等待 `a` 的逆计算完成呢?显然不必要,这两个求逆运算其实可以并行执行的。换句话说,调用 `Product()` 函数只需要等到 `a_inv` 和 `b_inv` 的计算完成。如下代码实现了并行计算方式:
    
    ```go
    func InverseProduct(a Matrix, b Matrix) {
        a_inv_future := InverseFuture(a)   // start as a goroutine
        b_inv_future := InverseFuture(b)   // start as a goroutine
        a_inv := <-a_inv_future
        b_inv := <-b_inv_future
        return Product(a_inv, b_inv)
    }
    ```
    
    `InverseFuture()` 函数以 `goroutine` 的形式起了一个闭包,该闭包会将矩阵求逆结果放入到 `future` 通道中:
    
    ```go
    func InverseFuture(a Matrix) chan Matrix {
        future := make(chan Matrix)
        go func() {
            future <- Inverse(a)
        }()
        return future
    }
    ```
    
    当开发一个计算密集型库时,使用 Futures 模式设计 API 接口是很有意义的。在你的包使用 Futures 模式,且能保持友好的 API 接口。此外,Futures 可以通过一个异步的 API 暴露出来。这样你可以以最小的成本将包中的并行计算移到用户代码中。(参见参考文件 18:[http://www.golangpatterns.info/concurrency/futures](http://www.golangpatterns.info/concurrency/futures))
    
    ## 链接
    
    - [目录](directory.md)
    - 上一节:[惰性生成器的实现](14.8.md)
    - 下一节:[复用](14.10.md)
    
    
    links
    file_download