解析线程池

来源:互联网 发布:ubuntu版本的区别 编辑:程序博客网 时间:2024/06/02 01:34

线程池是一种多线程处理形式,处理过程中将任务添加到队列,然后在创建线程后自动启动这些任务。线程池线程都是后台线程。每个线程都使用默认的堆栈大小,以默认的优先级运行,并处于多线程单元中。如果某个线程在托管代码中空闲(如正在等待某个事件),则线程池将插入另一个辅助线程来使所有处理器保持繁忙。如果所有线程池线程都始终保持繁忙,但队列中包含挂起的工作,则线程池将在一段时间后创建另一个辅助线程但线程的数目永远不会超过最大值。超过最大值的线程可以排队,但他们要等到其他线程完成后才启动。

服务器程序如何利用线程池来优化性能?
1、线程池管理器(ThreadPoolManager):用于创建并管理线程池
2、工作线程(WorkThread): 线程池中线程
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行。
4、任务队列:用于存放没有处理的任务。提供一种缓冲机制。

线程池功能:
应用程序可以有多个线程,这些线程在休眠状态中需要耗费大量时间来等待事件发生。其他线程可能进入睡眠状态,并且仅定期被唤醒以轮循更改或更新状态信息,然后再次进入休眠状态。为了简化对这些线程的管理,.NET框架为每个进程提供了一个线程池,一个线程池有若干个等待操作状态,当一个等待操作完成时,线程池中的辅助线程会执行回调函数。线程池中的线程由系统管理,程序员不需要费力于线程管理,可以集中精力处理应用程序任务

应用范围:
1、需要大量的线程来完成任务,且完成任务的时间比较短。 WEB服务器完成网页请求这样的任务,使用线程池技术是非常合适的。因为单个任务小,而任务数量巨大,你可以想象一个热门网站的点击次数。 但对于长时间的任务,比如一个Telnet连接请求,线程池的优点就不明显了。因为Telnet会话时间比线程的创建时间大多了。
2、对性能要求苛刻的应用,比如要求服务器迅速响应客户请求。
3、接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。突发性大量客户请求,在没有线程池情况下,将产生大量线程,虽然理论上大部分操作系统线程数目最大值不是问题,短时间内产生大量线程可能使内存到达极限,并出现”OutOfMemory”的错误。

代码示例:

//线程池示例using System;using System.Threading;public classTest{    //存放要计算的数值的字段    static double number1 = -1;    static double number2 = -1;    public static void Main()    {        //获取线程池的最大线程数和维护的最小空闲线程数        int maxThreadNum, minThreadNum;        int portThreadNum;        ThreadPool.GetMaxThreads(out maxThreadNum, out portThreadNum);        ThreadPool.GetMinThreads(out minThreadNum, out portThreadNum);        Console.WriteLine("最大线程数:{0}", maxThreadNum);        Console.WriteLine("最小线程数:{0}", minThreadNum);        //函数变量值        int x=15600;        //启动第一个任务:计算x的8次方        Console.WriteLine("启动第一个任务:计算{0}的8次方。", x);        ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc1), x);        //启动第二个任务:计算x的8次方根        Console.WriteLine("启动第二个任务:计算{0}的8次方根。", x);        ThreadPool.QueueUserWorkItem(new WaitCallback(TaskProc2), x);        //等待,直到两个数值都完成计算        while(number1 == -1 || number2 == -1);        //打印计算结果        Console.WriteLine("y({0}) = {1}", x, number1 + number2);        Console.Read();    }    //启动第一个任务:计算x的8次方    static void TaskProc1(object o)    {        number1 = Math.Pow(Convert.ToDouble(o), 8);    }    //启动第二个任务:计算x的8次方根    static void TaskProc2(object o)    {        number2 = Math.Pow(Convert.ToDouble(o), 1.0/8.0);    }}//池结构[HostProtection(SecurityAction.LinkDemand,Synchronization=true,ExternalThreading=true)]public static class ThreadPool{[Obsolete("ThreadPool.BindHandle(IntPtr)hasbeendeprecated.PleaseuseThreadPool.BindHandle(SafeHandle)instead.",false),SecurityPermission(SecurityAction.Demand,Flags=SecurityPermissionFlag.UnmanagedCode)]public static bool BindHandle(IntPtr osHandle){    if(osHandle == null){throw new ArgumentNullException("osHandle");}    bool flag = false;    bool success = false;    RuntimeHelpers.PrepareConstrainedRegions();    try    {        osHandle.DangerousAddRef(ref success);        flag = BindIOCompletionCallbackNative(osHandle.DangerousGetHandle());    }    finally    {        if(success)            osHandle.DangerousRelease();    }    return flag;}