7. a brief analysis of parallel development task and thread pool eight days Fun parallel development - the seventh day of a brief analysis of the task and the thread pool

Original: 8 days Fun parallel development - the seventh day of a brief analysis of the task and the thread pool

 

         In fact, when it comes to the one, we say that knowledge of the task is also to say about it, this one we started standing relationship between the "thread pool" and "mission" under the theory to understand, whether it is

Said thread or task, we are inevitably to be discussed under the thread pool, but after a .net 4.0, thread pool engines consider the future of scalability, already take advantage of multicore microprocessors

Architecture, as long as possible in the circumstances, we should try to use the task, rather than the thread pool.

 

First look at the structure of the task

From the figure we can see Task.Factory.StartNew () is equivalent to the seemingly created with ThreadPool.QueueUserWorkItem (), but please note that I have used in the form of TPL

Use the thread pool, to know the future task appears, has been advertised with less effort, lower performance overhead to PK original thread.

 

     Here CLR thread pool at a brief analysis, in fact, the thread pool has a concept called "global queue", and each time we use will have to use a QueueUserWorkItem

"Work Item", and "work item" into the "global queue" queued work threads last thread pool withdrawn in the form of a FIFO, the effect similar to FIG follows:

Here it must worth mentioning that, after the .net 4.0 "global queue" with a lock-free algorithms, compared to the previous version locking performance bottleneck "global queue" brings has been greatly improved. So the task

Commissioned thread pool are not only "global queue", and each worker thread "local queue", the effect as FIG.

Our first reaction is certainly "Local queue" What good can consider such a situation, when we new a task of "work items" will go "global queue" if our

task execution is very fast, then the "global queue" FIFO will very frequently, so is there any way to alleviate it? Our task when nested in the scene, "local queue" will produce an effect,

For example, a task which we have three task, then these three task will exist in the "Local queue" in.

复制代码
 1   class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             var task = Task.Factory.StartNew(() =>
 6             {
 7                 var task1 = Task.Factory.StartNew(Run1);
 8                 var task2 = Task.Factory.StartNew(Run2);
 9                 var task3 = Task.Factory.StartNew(Run3);
10 
11                 Task.WaitAll(new Task[] { task1, task2, task3 });
12             });
13 
14             Console.Read();
15         }
16 
17         public static void Run1() { Thread.Sleep(100000); }
18 
19         public static void Run2() { Thread.Sleep(100000); }
20 
21         public static void Run3() { Thread.Sleep(100000); }
22     }
复制代码

从图中可以看到,其实“局部队列“起到了一个分流的作用,也叫做”任务内联化“,”局部队列“采用的是”LIFO"的形式,其实这样的形式也是

为了提升性能之用,因为Run3送到“局部队列”中时可能还存在CPU的高速缓存中,所以从“局部队列”中取出来相对来说更快一点,最后的效

果就是Run3要理论上优先于Run2,Run1先执行。

     现在我们再来考虑这样一种情况,比如有两个人,一个人干完了分配给自己的所有活,而另一个人却还有很多的活,从人情上说,闲的人应

该接手点忙的人的活,同样,对应图中“线程2“跑完了“局部队列”中的所有任务,并且同时发现”全局队列“中已经没有可以跑的”任务“了,然而

“线程1”里面还有Run1,Run2,Run3,那么此时“线程2”采用“FIFO”的形式窃取“线程1”里面的任务。

    从上面种种情况我们看到,这些分流和负载都是普通ThreadPool.QueueUserWorkItem所不能办到的,所以说在.net 4.0之后,我们

尽可能的使用TPL,抛弃ThreadPool。

Guess you like

Origin www.cnblogs.com/zhang1f/p/11162829.html