NET 4.0 多任务编程 之三 改进的线程池

其实从.NET设计之初中就有并行编程技术的一些实现---多线程技术。多线程最大的问题就是难于使用和管理。因为它的复杂性,往往使用我们把注意力分散在如何管理多线程上,而致使我们的最初目的被淡化了。

在.NET 4 中就引入了“并行编程”来简化并行计算,虽然.NET 4.0中提出的并行编程的底层机制其实还是基于多线程的。但是他们之前最大的区别就是.NET 4.0中的并行编程更加方便和直观。

平行任务库(Task Parallel Library, 简称TPL)成为.NET 4.0各种新特性中最为闪耀的明星; 这个新特性的核心是Task, 底层支持就是.NET 4.0 线程池的重新实现.

我们知道,线程池基本功能包括:管理工作队列和管理执行这些工作的线程集。相应的,设计线程池需要考量的是:一、如何让工作快速进出队列,二、如何运用算法优化服务队伍的线程数目。下面我们着重比较下新旧线程池在这方面的不同。

关于进列和出列方面,原先的线程池提供了最简单的工作线程接口QueueUserWorkItem,简称QUWI。QUWI的使用很简单,通过QueueUserWorkItem这个方法,把一个委托放入队列等这稍后被执行:
    static void CreateAndWaitForWorkItems(int numWorkItems)
    {
        using (ManualResetEvent mre = new ManualResetEvent(false))
        {
            int itemsRemaining = numWorkItems;
            for (int i = 0; i < numWorkItems; i++)
            {

                ThreadPool.QueueUserWorkItem(()=>
                {
                    if (Interlocked.Decrement(ref itemsRemaining) == 0) mre.Set();

                });
            }
            mre.WaitOne();
        }


可以看出,原有的线程池存在着局限性题:
QUWI基本上对每个工作单元的一无所知,仅限于了解它的存在。这对工作单元的执行是重要的制约。比如,线程池不知道是否工程单元是否彼此相关,所以它必须假设他们都是完全独立的,线程池应用程序接口不提供任何辅助手段处理各个工作项之间的关系。 这样的限制带来的明显问题: 这就意味着我们不能重新安排工作,以优化执行,为了确保公平,独立工作单元通常按照FIFO的顺序执行。

由于线程池不提供处理关系的应用程序接口, 当多个工作项之间确实存在需要处理的关系时, 开发人员只能在工作项执行体中加入同步代码才能达到这一目的,导致程序的可读性下降, 当大量这样的代码出现时, 系统的可维护性和质量就受到威胁。同时,开发方式也受到影响. 由于API的这种限制, 开发人员更倾向于将"发射后不管"的任务放到线程池中执行, 而对于有同步或次序要求的任务, 更倾向于在独立的线程中执行。

你可能感兴趣的:(多线程,编程,.net,工作,算法)