我已经看到了一些在F#中将异步与并行相结合的例子。这是MSDN示例:http://msdn.microsoft.com/en-us/library/dd233250(v=vs.120).aspx 不是线程的低效使用吗?为什么要为许多可能长时间运行的IO类型操作使用新线程。难道基本上没有创建只会坐在那里等待的线程吗?
答案 0 :(得分:11)
快速回答:异步工作流是轻量级的用户空间线程。您可以创建大量此类异步工作流,这可以帮助以更自然的方式构建程序,假设它具有异步,并发或并行计算。单个本机线程可以运行任意数量的异步工作流,异步工作流可以从一个本机线程转移到另一个本机线程。这允许您的程序有效和高效地使用本机线程。
异步工作流的基本特征是可以阻止异步工作流中的操作,等待长时间运行(异步)操作的结果,而不会阻塞本机线程。这允许单个本机线程运行多个异步工作流(一次一个)。
在您链接到的特定示例中,Async.Parallel
用于并行执行多个长时间运行的操作。使用异步工作流程可以使程序的并行化版本结构简单,同时避免使用多个(昂贵的)本机线程。 所以,答案是否定的:这不会创建大量本机线程,只会等待。会发生什么(相对)少量的本机线程将运行这些异步工作流。当特定的异步工作流被阻塞,等待长时间运行的操作时,本机线程开始运行一些准备好继续的其他异步工作流。
关于并行编程,特别是异步工作流程存在问题。具体而言,异步工作流以(半)抢先方式执行。基本上,执行异步工作流以便在执行一些操作之后,即使特定的异步工作流不阻塞或等待长时间运行的操作,也将其排队,并且另一个工作流被出列以便执行。这对于并行性能来说是灾难性的,因为这意味着您的程序将使用与就绪工作流数量成比例的内存,这可能远远大于CPU内核的数量。为了最大化并行性能,最好使用协作调度。这是我为F#创建Hopac库的原因之一。