f# - 异步/并行组合

标签 f#

我见过一些在 F# 中结合异步和并行的例子。这是一个 MSDN 示例:http://msdn.microsoft.com/en-us/library/dd233250(v=vs.120).aspx 这不是对线程的低效使用吗?为什么要为许多可能长时间运行的 IO 类型操作使用新线程。这不是基本上创建了只会坐在那里等待的线程吗?

最佳答案

快速回答:异步工作流是轻量级的用户空间线程。您可以创建大量此类异步工作流,这有助于以更自然的方式构建您的程序,假设它具有异步、并发或并行计算。单个 native 线程可以运行任意数量的异步工作流,并且异步工作流可以从一个 native 线程转移到另一个 native 线程。这允许您的程序有效且高效地使用 native 线程。

异步工作流的基本特征是异步工作流中的操作可以被阻塞以等待长时间运行(异步)操作的结果,而不会阻塞 native 线程。这允许单个 native 线程运行多个异步工作流(一次一个)。

在您链接到的特定示例中,Async.Parallel 用于并行执行多个长时间运行的操作。使用异步工作流使程序的并行版本在结构上变得简单,同时避免使用多个(昂贵的) native 线程。 因此,答案是否定的:这不会创建大量只会等待的 native 线程。发生的情况是(相对)少量的 native 线程将运行这些异步工作流。当一个特定的异步工作流被阻塞,等待一个长时间运行的操作时, native 线程开始运行其他一些准备好继续的异步工作流。

关于并行编程,尤其是异步工作流存在问题。具体来说,异步工作流以(半)抢占方式执行。基本上,执行异步工作流是为了在执行一定数量的操作后,将一个特定的异步工作流排入队列,即使它不阻塞或等待长时间运行的操作,另一个工作流将出队执行。这对于并行性能来说是灾难性的,因为这意味着您的程序将使用与就绪工作流的数量成比例的内存,这可能比 CPU 内核的数量大得多。为了最大化并行性能,最好使用协作调度。这是我创建 Hopac 的原因之一F# 库。

关于f# - 异步/并行组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26040882/

相关文章:

.net - F# 中 OCaml 的 set_signal 等效项

f# - 如何使用无法在 F# 中控制其类型定义的操作数来定义重载运算符?

c# - F# 中的接口(interface)对象语法

c# - 在 .NET 上更快地解析数字

generics - 保持部分应用的函数通用

asynchronous - F# 异步工作流/任务结合免费 monad

javascript - 将 Selenium 代码与 F# Canopy 结合使用

csv - 如何根据参数读取属性值

c# - 在 F# 交互中获取调试器上下文

.net - 非统一实例化的用法是什么意思?