若考虑使用多线程访问资源,需注意线程的互斥和同步,防治发生死锁。刚刚看了使用C#线程池的代码,现在把心得记录下来:
1.定义信号量Semaphore,控制线程同步问题
public class Semaphore
{
private int _count;
public Semaphore():this(1){}
public Semaphoere(int count)
{
_count = count;
}
public void P()
{
//如果无资源可访问,Monitor阻塞当前线程,等待激活
if(_count<=0) Monitor.Wait(this, Timeout.Infinite);
count--;
}
public void V()
{
count++;
//其它线程释放资源后,激活被堵塞队列中的一个线程
Monitor.Pulse(this);
}
}
2.实现线程池
public class ThreadPool
{
private static int _maxThreadsNum = 5; //线程最大数
private static ArrayList _workThreads; //线程队列
private static Semaphore _semaphore; //信号量
static Queue _waitingCallbacks; //待处理任务队列
static int _inUseThreads; //当前处理任务的线程数
static ThreadPool()
{
_waitingCallbacks = new Queue();
_workerThreads = new ArrayList();
_inUseThreads = 0;
_semaphore= new Semaphore(0);
for(int i=0; i<_maxThreadsNum ; i++)
{
Thread newThread = new Thread(new ThreadStart(ProcessQueuedItems));
_workerThreads.Add(newThread);
newThread.Name = "ManagedPoolThread #" + i.ToString();
newThread.IsBackground = true;
newThread.Start();
}
}
//生产者
public static InsertQueueItem(WaitCallBack callback)
{
//互斥访问Queue
lock(_waitingCallbacks.SyncRoot)
{
_waitingCallbacks.Enqueue(callback);
_semaphore.V();
}
}
//消费者
public static ProcessQueuedItems()
{
while(true)
{
WaitCallBack callback = null;
while(null==callback)
{
//互斥访问Queue
lock(_waitingCallbacks.SyncRoot)
{
if(_waitingCallbacks.count>0)
callback = _waitingCallbacks.Dequeue();
}
if(null==callback) _semaphore.P();
}
//Interlocked用于保证多线程同步修改一个对象
Interlocked.Increment(ref _inUseThreads);
callback.CallBack();
Interlocked.Decrement(ref _inUseThreads);
}
}
}
上述代码没有经过调试,只是给出了多线程处理任务的基本流程,仅供参考。

浙公网安备 33010602011771号