Files
the-way-to-go_ZH_CN/eBook/14.9.md

48 lines
2.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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)