什么是期货?
Posted
技术标签:
【中文标题】什么是期货?【英文标题】:What are futures? 【发布时间】:2010-09-09 23:24:48 【问题描述】:这与惰性求值有关。
【问题讨论】:
期货不一定与惰性评估有关。事实上,对于很多用例,Lazy futures 正是你不需要的:IO、网络等...... “期货”目前正在通过 javascript 获得大量曝光!但是 JavaScript 领域的术语是“延迟”和“承诺”。 【参考方案1】:Future 封装了延迟计算,通常用于将惰性求值硬塞到非惰性语言中。第一次评估未来时,运行评估它所需的代码,并将未来替换为结果。
由于future被替换,后续的求值不会再次执行代码,只是简单的产生结果。
【讨论】:
【参考方案2】:当您创建未来时,会启动一个新的后台线程,开始计算实际值。如果你请求future的值,它将阻塞直到线程完成计算。当您需要并行生成一些值并且不想手动跟踪所有值时,这非常有用。
对于 Ruby,请参阅 lazy.rb,或 Scala, futures, and lazy evaluation。
它们可能可以用任何带有线程的语言来实现,尽管在 C 这样的低级语言中显然比在高级函数式语言中更难。
【讨论】:
AFAIK,期货在实际请求之前不会开始执行。期货通常用于构建惰性屏障,例如为了实现一个无限的结构。如果期货在创建后立即开始执行,它们将不适合这样做。 @012...:查看我发布的链接,它们很好地概述了期货。 en.wikipedia.org/wiki/… 似乎是一个更明确的参考。 (哈!***!) 总结:Futures 开始时不是同时执行的;现在有些人将它们定义为这样做,并将原始概念重命名为 Promise。 @0124816: 并非所有期货都是在请求时执行,而不是在创建时执行。只有 lazy 期货有这种行为。在某些情况下,Lazy 很糟糕,future 在定义后就开始执行。【参考方案3】:有一个关于期货的Wikipedia article。简而言之,这是一种使用未知值的方法。然后可以按需计算该值(惰性求值),也可以与主计算同时进行。
C++ 示例如下。
假设您要计算两个数字的总和。您可以使用典型的 Eager 实现:
int add(int i, int j) return i + j;
// first calculate both Nth_prime results then pass them to add
int sum = add(Nth_prime(4), Nth_prime(2));
或者您可以使用 C++11 的 std::async
使用期货方式,它返回一个 std::future
。在这种情况下,add
函数只有在尝试使用尚未计算的值时才会阻塞(也可以创建一个纯粹的惰性替代方案)。
int add(future<int> i, future<int> j) return i.get() + j.get();
int sum = add(async(launch::async, []() return Nth_prime(4); ),
async(launch::async, []() return Nth_prime(2); ));
【讨论】:
【参考方案4】:大家提到期货都是为了懒计算。然而,另一个没有宣传的用途是使用 Futures for IO。特别是它们对于加载文件和等待网络数据很有用
【讨论】:
【参考方案5】:The Wiki Article 很好地概述了期货。该概念通常用于并发系统中,用于调度可能尚未计算或尚未计算的值的计算,此外,其计算可能已经或可能尚未进行。
来自文章:
未来与 计算其的特定线程 价值。可以开始这个计算 要么在未来到来时热切地 创建,或懒惰,当它的价值是 首先需要。
文章中没有提到,future 是Monad,因此可以将future 值的函数投影到monad 中,以便在future 可用时将它们应用于future 值,从而产生另一个future,而future 又代表该函数的结果。
【讨论】:
【参考方案6】:Futures 也用于某些设计模式,特别是实时模式,例如 ActiveObject 模式,它将方法调用与方法执行分开。未来被设置为等待完成的执行。当您需要从多线程环境迁移到与单线程环境进行通信时,我倾向于看到它。在某些情况下,某个硬件没有内核支持线程,在这种情况下使用期货。乍一看,你将如何沟通并不明显,但令人惊讶的是,未来让它变得相当简单。我有一些 c# 代码。我会挖出来贴出来。
【讨论】:
【参考方案7】:This blog post 给出了一个非常透彻的解释以及一个你如何自己实现未来的例子。我真的推荐它:)
【讨论】:
以上是关于什么是期货?的主要内容,如果未能解决你的问题,请参考以下文章