不会C# 却想要用C# 做一个快速同步的程序。 多线程,线程池难免要用。 用了一下 .Net 系统所带的 ThreadPool, 可是启动的线程数目,无论如何都不受我控制。 SetMaxThreads 之类的函数也调用了,可是就是没有效果。 没办法治好自己写了一个线程池。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
namespace QuickSync
{
class ThreadEntry
{
public TaskParameter ThreadParam { get; set; }
public bool Idle { get; set; }
public ThreadEntry(VThreadPool vp, ParameterizedThreadStart start, int n)
{
pool = vp;
nIdx = n;
Idle = true;
ThreadParam = null;
thread = new Thread(start);
thread.Start(this);
}
public void Run()
{
while (true)
{
evnt.WaitOne();
if (pool.stop == true)
{
Console.WriteLine("Thread ID {0} exit ... ", nIdx);
break;
}
if (ThreadParam != null)
{
ThreadParam.callback(ThreadParam.mObj);
ThreadParam = null;
pool.ReleaseThread(nIdx);
}
}
}
public void TriggerRun(TaskParameter tParam)
{
if (tParam != null)
{
ThreadParam = tParam;
evnt.Set();
}
}
public void Stop(bool bForce)
{
evnt.Set();
if (bForce)
{
thread.Abort();
}
}
private AutoResetEvent evnt = new AutoResetEvent(false);
private VThreadPool pool;
private Thread thread;
private int nIdx;
};
class TaskParameter
{
public WaitCallback callback;
public object mObj;
public TaskParameter(WaitCallback wc, object aObj)
{
callback = wc;
mObj = aObj;
}
};
class VThreadPool
{
public volatile bool stop = false;
public void Stop(bool bForce)
{
stop = true;
threadSemaphore.Release();
taskEvent.Set();
for (int i = 0; i < threads.Length; i++)
{
threads[i].Stop(bForce);
}
}
private int AllocThreadIdx()
{
int n = -1;
threadListLock.WaitOne();
for (int i = 0; i < threads.Length && stop == false; i++)
{
nSearchIdx = (nSearchIdx + 1) % threads.Length;
if (threads[nSearchIdx].Idle == true)
{
threads[nSearchIdx].Idle = false;
n = nSearchIdx;
break;
}
}
threadListLock.ReleaseMutex();
return n;
}
public void ReleaseThread(int idx)
{
if (idx >= 0 && idx < threads.Length)
{
threadListLock.WaitOne();
threads[idx].Idle = true;
threadSemaphore.Release();
threadListLock.ReleaseMutex();
}
}
private void triggerThread(int idx)
{
if (stop == false && idx >= 0 && idx < threads.Length)
{
TaskParameter tParam = GetThreadParame();
threads[idx].TriggerRun(tParam);
}
}
public void ScheduleThreadProcM()
{
int index;
while (stop == false)
{
threadSemaphore.WaitOne();
index = AllocThreadIdx();
if (index >= 0 && index < threads.Length && taskList.Count <= 0)
{
taskEvent.WaitOne();
}
triggerThread(index);
}
}
private static void ScheduleThreadProc(object oInput)
{
VThreadPool vThreadPool = (VThreadPool)oInput;
if (vThreadPool != null)
{
vThreadPool.ScheduleThreadProcM();
Console.WriteLine("ScheduleThreadProc exit ... ");
}
}
private void SingThreadProc(object obj)
{
ThreadEntry threadEny = (ThreadEntry)obj;
threadEny.Run();
}
private bool CreateThreads(int n)
{
if (n <= 0)
{
n = 3;
}
if (threads != null)
{
return false;
}
threads = new ThreadEntry[n];
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new ThreadEntry(this, SingThreadProc, i);
}
threadSemaphore = new Semaphore(n, n);
ScheduleThread.Start(this);
return true;
}
public VThreadPool(int n)
{
CreateThreads(n);
}
public bool QueueUserWorkItem(WaitCallback callback)
{
return QueueUserWorkItem(callback, null);
}
public bool QueueUserWorkItem(WaitCallback callback, object state)
{
taskListLock.WaitOne();
TaskParameter nParam = new TaskParameter(callback, state);
taskList.AddLast(nParam);
taskEvent.Set();
taskListLock.ReleaseMutex();
return true;
}
private TaskParameter GetThreadParame()
{
TaskParameter nParam = null;
if (taskList.Count > 0)
{
taskListLock.WaitOne();
nParam = taskList.First.Value;
taskList.RemoveFirst();
taskListLock.ReleaseMutex();
}
return nParam;
}
LinkedList<TaskParameter> taskList = new LinkedList<TaskParameter>();
Mutex taskListLock = new Mutex();
AutoResetEvent taskEvent = new AutoResetEvent(false);
ThreadEntry[] threads = null;
Mutex threadListLock = new Mutex();
Semaphore threadSemaphore = null;
Thread ScheduleThread = new Thread(ScheduleThreadProc);
int nSearchIdx = -1;
}
}