From 5305caadb018cb7ea7a08a9d778c2631ca04961f Mon Sep 17 00:00:00 2001 From: liracle Date: Wed, 15 Feb 2017 23:31:46 +0800 Subject: [PATCH] commit 14.9.md, done --- eBook/14.9.md | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 eBook/14.9.md diff --git a/eBook/14.9.md b/eBook/14.9.md new file mode 100644 index 000000000..2e23b24eb --- /dev/null +++ b/eBook/14.9.md @@ -0,0 +1,47 @@ +# 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) { + 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) \ No newline at end of file