使用System.Threading.Tasks.Parallel创建线程池中新的线程? [英] Using System.Threading.Tasks.Parallel create new thread in the thread pool?

查看:190
本文介绍了使用System.Threading.Tasks.Parallel创建线程池中新的线程?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我不明白的是正确的......所有的Parallel类问题:(

Maybe I did not understand it right ... all the Parallel class issue :(

但是,从我读了,我明白,当我使用并行其实我调动所有存在的线程池的一些任务/任务的线程。

But from what I am reading now, I understand that when I use the Parallel I actually mobilize all the threads that exists in the threadPool for some task/mission.

例如

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

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

So the Parallel.ForEach in this case is mobilizing all the threads that exists in the threadPool for the 'DoSomething' task/mission.

但是否调用Parallel.ForEach将创建任何新线程呢?

But does the call Parallel.ForEach will create any new thread at all?

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

Its clear that there will be no 1000 new threads. But lets assume that there are 1000 new threads, some case that the threadPool release all the thread that it hold so, in this case ... the Parallel.ForEach will create any new thread?

推荐答案

简短的回答: Parallel.ForEach()并没有动员所有线程。而且任何的操作,日程安排上的一些工作线程池(其中 Parallel.ForEach()做)可能会导致创建新线程池中。

Short answer: Parallel.ForEach() does not "mobilize all the threads". And any operation that schedules some work on the ThreadPool (which Parallel.ForEach() does) can cause creation of new thread in the pool.

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

Long answer: To understand this properly, you need to know how three levels of abstraction work: Parallel.ForEach(), TaskScheduler and ThreadPool:

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

  1. Parallel.ForEach() (and Parallel.For()) schedule their work on a TaskScheduler. If you don't specify a scheduler explicitly, the current one will be used.

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

Parallel.ForEach() splits the work between several Tasks. Each Task will process a part of the input sequence, and when it's done, it will request another part if one is available, and so on.

多少工作旨意 Parallel.ForEach()创建?由于许多人视为的TaskScheduler 将让它运行。在这样做的方法是,每个工作首先,当它开始执行入队自身的副本(除非这样做会违反<一href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.paralleloptions.maxdegreeofparallelism.aspx"相对=nofollow> MaxDegreeOfParallelism ,如果​​你把它设置)。这样一来,实际的并发级别是最高的的TaskScheduler

How many Tasks will Parallel.ForEach() create? As many as the TaskScheduler will let it run. The way this is done is that each Task first enqueues a copy of itself when it starts executing (unless doing so would violate MaxDegreeOfParallelism, if you set it). This way, the actual concurrency level is up to the TaskScheduler.

此外,第一工作实际上将当前线程上执行,如果的TaskScheduler 支持它(这是完成使用 RunSynchronously() )。

Also, the first Task will actually execute on the current thread, if the TaskScheduler supports it (this is done using RunSynchronously()).

默认的TaskScheduler 只是加入队列每个工作线程池队列。 (事实上​​,它更复杂,如果你开始一个工作从另一个工作,但这不是与此有关。)其他的TaskScheduler S能够做完全不同的事情,其中​​有些(如<一个href="http://msdn.microsoft.com/en-us/library/system.threading.tasks.taskscheduler.fromcurrentsynchronizationcontext.aspx"相对=nofollow> TaskScheduler.FromCurrentSynchronizationContext() )是完全不适合与 Parallel.ForEach()使用

The default TaskScheduler simply enqueues each Task to the ThreadPool queue. (Actually, it's more complicated if you start a Task from another Task, but that's not relevant here.) Other TaskSchedulers can do completely different things and some of them (like TaskScheduler.FromCurrentSynchronizationContext()) are completely unsuitable for use with Parallel.ForEach().

线程池使用一个相当复杂的算法来确定到底有多少线程应该在任何给定时间内运行。但在这里最重要的是,安排新的工作项目的可以的产生一个新的线程的创建(尽管不一定马上)。而且,由于与 Parallel.ForEach(),总有一些项目排队等待执行时,它完全取决于线程池来决定的线程数。

The ThreadPool uses quite a complex algorithm to decide exactly how many threads should be running at any given time. But the most important thing here is that scheduling new work item can cause the creating of a new thread (although not necessarily immediately). And because with Parallel.ForEach(), there is always some item queued to be executed, it's completely up to the internal algorithm of ThreadPool to decide the number of threads.

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

Put together, it's pretty much impossible to decide how many threads will be used by a Parallel.ForEach(), because it depends on many variables. Both extremes are possible: that the loop will run completely synchronously on the current thread and that each item will be run on its own, newly created thread.

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

But generally, is should be close to optimal efficiency and you probably don't have to worry about all those details.

这篇关于使用System.Threading.Tasks.Parallel创建线程池中新的线程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆