如何下手进行高效的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(); } }