问题
I have seen some examples of combining async with parallel in F#. Here's an MSDN sample: http://msdn.microsoft.com/en-us/library/dd233250(v=vs.120).aspx Isn't that an inefficient use of threads? Why would you want to use new threads for many, potentially long running, IO type operations. Isn't that basically creating threads that will just sit there and wait?
回答1:
Quick answer: Asynchronous workflows are lightweight, user-space threads. You can create large numbers of such asynchronous workflows, which can help to structure your program in a more natural manner, assuming it has asynchronous, concurrent or parallel computations. A single native thread can run arbitrary numbers of asynchronous workflows and asynchronous workflows can transfer from one native thread to another. This allows your program to make effective and efficient use of native threads.
The essential feature of asynchronous workflows is that an operation in an asynchronous workflow can be blocked waiting for the result of a long running (asynchronous) operation without blocking a native thread. This allows a single native thread to run multiple asynchronous workflows (one at a time).
In the particular example that you linked to, Async.Parallel
is used to execute multiple long running operations in parallel. Use of asynchronous workflows makes the parallelized version of the program structurally simple, while avoiding the use of multiple (expensive) native threads. So, the answer is no: This doesn't create a large number of native threads that would simply wait. What happens is that a (relatively) small number of native threads will run those asynchronous workflows. When a particular asynchronous workflow becomes blocked, waiting for a long running operation, the native thread starts running some other asynchronous workflow that is ready to be continued.
Regarding parallel programming, in particular, there is a problem with asynchronous workflows. Specifically, asynchronous workflows are executed in a (semi) preemptive manner. Basically, asynchronous workflows are executed so that after performing some number of operations, a particular asynchronous workflow is enqueued, even if it doesn't block or wait for a long running operation, and another workflow is dequeued for execution. This is disastrous for parallel performance, because it means that your program will use memory proportional to the number of ready workflows, which can be much larger than the number of CPU cores. For maximizing parallel performance, it is better to use cooperative scheduling. This is one of the reasons I created the Hopac library for F#.
来源:https://stackoverflow.com/questions/26040882/async-parallel-combined