如何下手进行高效的c#线程池设计

在实际使用中,容易造成CPU占用偏高,笔者分析认为是由于信号量本身的缺点造成的,因此笔者重新设计了一款更高效的c#线程池,完全不使用waithandle之类的阻塞线程,而是使用更为简单的最大线程数值(一个long整数)来控制线程的运行。如果超过指定的线程数,那么保存在hash表中的线程进入等待队列,当有空闲位置时,才会释放出一个等待队列中的线程启动并运行。

笔者粗略地计算了下,此种方法比基于信号量的效率要高30左右,性能提高是显著的^_^pdf,下面为大家展示代码。

    public class MyThreadManager : MyThreadPool, iThreadManager
    { //线程池的启动、停止控制大同小异,不再赘述pdf
        private bool bStart;
        private bool bPause;
        private bool bStoped;

        public bool Running
        {
            get { return bStart && !bPause && !bStoped; }
        }
        public MyThreadManager(int num):base(num)
        {
            ControlCallback = new ThreadControl(Run);
            bStart = false;
            bPause = false;
            bStoped = false;
        }

        public virtual void Start()
        {
            bStart = true;
            bPause = false;pdf
            bStoped = false;
        }

        public void Stop()
        {
            bPause = true;
            bStart = false;
            bStoped = false;
        }

        public void Pause()
        {
            bStoped = true;
            bStoped = false;
            bPause = false;
        }

        public void Resume()
        {
            bPause = false;
            bStoped = false;
            bStart = true;
        }

        public void Run()
        {
            while(!bStart || bPause || bStoped){
                if (bStoped)
                {
                    Thread.CurrentThread.Abort();
                }
                Thread.Sleep(20);
            }
            while (Interlocked.Read(ref iRunningThreadNum) > Interlocked.Read(ref iMaxThreadNum))
            {
                Thread.Sleep(20);
            }
            Interlocked.Increment(ref iRunningThreadNum); //增加线程池中运行的线程数量
        }
    }

    public class MyThreadPool
    {
        protected Hashtable  m_Pool;
        protected Queue<string> m_Queue;

        protected ThreadControl m_control;

        public ThreadControl ControlCallback
        {
            set
            {
                m_control = value;
            }
            get
            {
                return m_control;
            }
        }

        protected long iMaxThreadNum;
        public  long MaxThreadNum
        {
            get
            {
                return Interlocked.Read(ref iMaxThreadNum);
            }
        }

        private long iQueueSize;

        protected long iRunningThreadNum;

        public long RunningThreadNum
        {
            get { return Interlocked.Read(ref iRunningThreadNum); }
        }

        public MyThreadPool(int num)
        {
            iMaxThreadNum = num;
            iRunningThreadNum = 0;
            iQueueSize = 0;
            m_Pool = new Hashtable(num);
            m_Queue = new Queue<string>();
        }

        public void QueueWorkItem(ThreadCallback callback, object obj)
        {

            Thread thread = new Thread(delegate()
            {
                if (m_control != null)
                    m_control();
                callback(obj); //这里是实际执行的函数
                m_Pool.Remove(Thread.CurrentThread.Name); //将当前线程移出线程池
                Interlocked.Decrement(ref iRunningThreadNum); //运行线程数递减
                ReleaseQueue(); //释放等待队列中的线程
            });
            string threadGuid = Guid.NewGuid().ToString();
            thread.Name = threadGuid; //保证线程命名唯一
            m_Pool.Add(threadGuid,thread);
            if (Interlocked.Read(ref iRunningThreadNum) < Interlocked.Read(ref iMaxThreadNum))
            {
                thread.Start();
            }
            else
            {
                m_Queue.Enqueue(thread.Name);
                Interlocked.Increment(ref iQueueSize);
            }
        }

        private void ReleaseQueue() //如果等待队列中有线程存在则释放一个,并做减计数
        {
            if (Interlocked.Read(ref iQueueSize) > 0)
            {
                string threadname = "";
                lock (m_Queue)
                {
                   threadname = m_Queue.Dequeue();
                   Interlocked.Decrement(ref iQueueSize);
                }
                Thread t = m_Pool[threadname] as Thread;
                t.Start();
            }
        }
    }

    public interface iThreadManager
    {

        void Start();
        void Stop();
        void Pause();
        void Resume();

        void Run();
    }
}
posted @ 2011-07-16 19:38  ph580  阅读(630)  评论(1编辑  收藏  举报