特别是,我正在考虑使用TPL来启动(并等待)外部进程。在决定启动另一个任务之前,TPL是否会查看总机器负载(CPU和I / O)(因此 - 在我的情况下是另一个外部进程)?
例如:
我有大约100个需要编码或转码的媒体文件(例如从WAV到FLAC或从FLAC到MP3)。通过启动外部进程(例如FLAC.EXE或LAME.EXE)来完成编码。每个文件大约需要30秒。每个进程主要是CPU绑定的,但那里有一些I / O.我有4个内核,所以最糟糕的情况(通过将解码器传输到编码器中进行代码转换)仍然只使用2个内核。我想做点什么:
Parallel.ForEach(sourceFiles,
sourceFile =>
TranscodeUsingPipedExternalProcesses(sourceFile));
这会启动100个任务(因此200个外部进程竞争CPU)吗?或者它会看到CPU忙,一次只做2-3次?
答案 0 :(得分:21)
答案 1 :(得分:2)
简短的回答是:不。
在内部,TPL使用标准ThreadPool
来安排其任务。所以你实际上在询问ThreadPool
是否考虑了机器负载,而不是。限制同时运行的任务数量的唯一因素是线程池中的线程数量,没有别的。
外部流程准备就绪后,是否可以将其报告给您的应用程序?在这种情况下,您不必等待它们(保持线程占用)。
答案 2 :(得分:-1)
使用TPL / ThreadPool进行测试以安排执行循环旋转的大量任务。使用外部应用程序我使用proc亲和力将其中一个核心加载到100%。活动任务的数量从未减少。
更好的是,我运行了同一个CPU密集型.NET TPL启用应用程序的多个实例。所有应用程序的线程数相同,并且从未低于核心数,即使我的机器几乎无法使用。
除了理论之外,TPL使用可用的核心数,但从不检查它们的实际负载。我认为这是一个非常糟糕的实施。