使用System.Threading.Tasks.Parallel创建线程池中新的线程?(Using

2019-07-29 16:04发布

也许我不明白它的权利...所有的Parallel类问题:(

但是,从我现在看书,我明白,当我使用并行其实我动员中存在的线程池的一些任务/任务的所有线程。

例如

  var arrayStrings = new string[1000];
  Parallel.ForEach<string>(arrayStrings, someString =>
  {
       DoSomething(someString);
  });

因此,在这种情况下,Parallel.ForEach动员中存在的线程池的“DoSomething的”任务/任务的所有线程。

但通话Parallel.ForEach将创建在所有任何新的线程?

它明确表示,不会再有1000个新的线程。 但是让我们假设有1000个新主题,一些情况下,该线程池释放所有的线程,它持有如此,在这种情况下...的Parallel.ForEach将创建任何新的线程?

Answer 1:

简短的回答: Parallel.ForEach()没有“调动所有线程”。 和时间表上的一些工作的任何操作ThreadPool (这Parallel.ForEach()一样)可能会导致池中新线程的创建。

龙答:要正确地理解这一点,你需要知道如何三个层次的抽象作品: Parallel.ForEach() TaskSchedulerThreadPool

  1. Parallel.ForEach()Parallel.For()安排他们在工作TaskScheduler 。 如果你没有明确指定一个调度, 当前一个将被使用。

    Parallel.ForEach()分裂之间的几个工作Task秒。 每个Task将处理输入序列的一部分,并且当它这样做,它会要求另一部分(如果可用),依此类推。

    有多少Task意志Parallel.ForEach()创建? 之多TaskScheduler会让它运行。 这样做的方式是,每个Task就开始执行(除非这样做会违背当第一次入队的自身的副本MaxDegreeOfParallelism ,如果设置了)。 这样一来,实际的并发级别是达TaskScheduler

    此外,第一Task将实际执行当前线程上,如果TaskScheduler支持它(这是用做RunSynchronously()

  2. 默认TaskScheduler简单地排入每个TaskThreadPool队列。 (实际上,如果你开始一个更复杂的Task ,从另一个Task ,但在这里,这是不相关的。)其他TaskScheduler S能够做完全不同的事情,他们中的一些(如TaskScheduler.FromCurrentSynchronizationContext()是完全不适合与使用Parallel.ForEach()

  3. ThreadPool使用一个相当复杂的算法来决定到底有多少线程应该在任何给定时间运行。 但是,这里最重要的是,安排新的工作项目可能会导致一个新的线程的创建(虽然不一定是立即)。 而由于与Parallel.ForEach()总是有一些项目排队等待执行,这完全取决于内部算法ThreadPool来决定的线程数。

放在一起,这几乎是不可能决定多少线程将被用来Parallel.ForEach()因为它取决于许多变量。 两个极端是可能的:环路将在当前线程,并且每个项目将其自己的,新创建的线程上运行,运行完全同步。

但是总体来说,应该是接近最佳的效率,你可能不必担心所有这些细节。



Answer 2:

Parallel.Foreach没有创建新的线程,也没有“调动所有线程”。 它使用线程池线程的数量有限,并提交任务,它们并行执行。 在目前执行的默认设置是使用每个核心一个线程。



Answer 3:

我觉得你有这个错误的方式轮。 从并行编程模式 ,你会看到,Parallel.ForEach只是真的语法糖。

该Parallel.ForEach在很大程度上归结为这样的事情,

for (int p = 0; p < arrayStrings.Count(); p++)
{
    ThreadPool.QueueUserWorkItem(DoSomething(arrayStrings[p]);
}

线程池需要调度的照顾。 周围有线程池的调度程序的行为在一定程度上,如果你有兴趣一些优秀的文章,但是这无关TPL。



Answer 4:

并行完全不使用线程处理 - 它调度任务的任务框架。 这则拥有调度和默认调度进入线程池。 这人会设法找到线程咕数(4.5比4.0更好)和线程池可以慢慢旋转起来的新线程。

但是,这并不是parallel.foreach的functoin;)

该Parallel.ForEach将创建任何新的线程???

它永远不会。 正如我所说的 - 它有1000的foreach,那么队列10.000任务点。 任务工厂调度会做什么编程做((你可以取代它)一般情况下,默认情况下 - 是的,慢慢的新主题将涌现在合理范围内。



文章来源: Using System.Threading.Tasks.Parallel create new thread in the thread pool?