Download source files - 3 Kb
Download demo project - 24 Kb
Introduction
On many occasions we need to utilize mutiple threads to boost the system performance. The logic
for each thread is almost the same, but we need to manage these threads. If the system is busy, we
create more threads, otherwise we kill some thread to avoid the extra overhead.
I have done a couple of projects involving the multiple-thread management. At last I decided to
write a class to wrap this machenism. This class can dynamically allocate threads and assign jobs to
these worker threads. You derive your own classes and you do not need to know the underlying machanism
to handle the mutiple threading and synchronization between these threads. However, you need to make
your worker classes thread safe since your objects may be assigned to different threads each time.
The another thing I want to demonstrate is the using the feature of IOCompletion Port. I found that
it is amazing easy and useful, especially when used as a way to transfer data between threads.
Usage
To use the thread pool class you need to derive your worker class from IWorker
and
your job class from IJobDesc
. The processing logic must be embedded within the member
function IWorker::ProcessJob(IJobDesc* pJob)
. After you are finished, you can declare
a thread pool like this:
CThreadPool pool;
pool.Start(6, 10);
pool.Stop();
The Start
function has two parameters. The first argument is the minimum number
of the worker threads this thread pool object should spawn. The second argument indicates the maximum
number of worker thread within this thread pool. If the thread pool is very busy working on the
assigned jobs it will automatically spawn more worker threads. On the other hand, when the thread
pool is idle some threads will be removed from the pool. Fine-tune these two parameters to get the
best performance.
To assign jobs to the thread pool for processing, simply call the function
pool.ProcessJob(pJob, pWorker);
You must make sure that your derived worker class is thread-safe since a worker instance
may be on multiple threads simultaneously. You have no control as to whether the process is on the same
thread as the last time or not.
Note
If the processing takes a very long time, when you call Stop()
, the processing may not
finished immediately. The Stop()
function will wait for a maximum of 2 minutes and then
return. This function has an optional argument. If this argument is set to true, the function will
terminate these worker threads anyway. If this argument is set to false, these worker threads will not
get terminated harshly and still live. Under this situation, you have to take care that the worker
object may not exist after calling Stop()
and you will get an access violation error
if you attempt to access them.
The job object must be generated on the heap using new
operator. After the process ends
it will automatically deleted by the framework.