KMThreadPool: 5 – Thread Pool Step 3:Enter Thread Pool

来源:互联网 发布:pc游戏优化不好 编辑:程序博客网 时间:2024/06/05 05:32

5 – Thread Pool Step 3:Enter Thread Pool

Welcome to the big sha-bang. TheKMThreadPool class is the container for all the threads and all the tasks.There’s only a few functions we’ll need outside of the library in order to usethe pool properly, but for now, lets look at what members this class contains:

private:
         KMQueue<KMTask*>         m_qtaskList;
         vector<KMThread*>         m_vthreads;
         unsigned int           m_nactive;
         volatile bool m_bprocess;
         //Singleton
         static KMThreadpool m_instance;

So we have our m_qtaskList and m_vthreads – pretty self-explanitory, then we have acount of the number of active threads (this will become relative in a moment),and then — Hey! There’s thatvolatile jerk I talked about on the last page! Well, hecomes in handy here because thatbool is very important; he’s used to indicatethat the thread pool is actively delegating tasks to the threads (so you candelay the start of or suspend task processing). Then we have our staticSingleton instance. We only ever need 1 thread pool, right?

Here, we have the primaryfunctions you’ll need to actually run the thread pool. There is no updatefunction, just start it and stop it. Easy as Π.

void Initialize(unsigned int uiTryMinNumThreads,
                  unsigned int uiTryMaxNumThreads);
void Shutdown();
void AddTask(KMTaskFunc task, IKMTaskData* data);
void BeginProcessing();
void StopProcessing();

These functions are what you’regoing to use to make your program interact with the thread pool.

Initialize()

First off is Initialize(). Someof you are looking at it, and are wondering why I have “uiTryMinNumThreads” and “uiTryMaxNumThreads” Well, the reason is simple: WithuiTryMinNumThreads, that’s the lowest number of threads yourprogram will try to create. If, for some reason, the creation fails on creatingthe minimum, the thread pool will not initialize.uiTryMaxNumThreads is also the same logic, however, if thecomputer cannot create the exact number of max threads, that’s OK – We stillhave the minimum.

void KMThreadpool::Initialize(unsigned int uiTryMinNumThreads,
                                unsigned int uiTryMaxNumThreads)
{
         unsigned int i;
         //Create the threads
         m_vthreads.assign(uiTryMinNumThreads, NULL);
 
         //Initialize the min number of threads
         for(i = 0; i < uiTryMinNumThreads; ++i)
         {
                  m_vthreads[i] = new KMThread();
                  m_vthreads[i]->Begin();
                  if(m_vthreads[i]->isRunning())
                  {
                       ++m_nactive;
                  }
         }
         //Try to initialize the max number of threads. If one fails,
         //we stop.
         for(i = uiTryMinNumThreads; i < uiTryMaxNumThreads; ++i)
         {
                  KMThread* trythread = new KMThread();
                  trythread->Begin();
                  if(trythread->isRunning())
                  {
                       m_vthreads.push_back(trythread);
                       ++m_nactive;
                  }
                  else
                  {
                       delete trythread;
                       break;
                  }
         }
}

Note: A good portion of this code is meant foreducational purposes – so as not to overly confuse people, a lot oferror-checking has been omitted. You can add it if you’d like – it’s not allthat difficult.

BeginProcessing() &StopProcessing()

Lets take a moment to look atthese functions. Mainly all they do is toggle them_bprocess bool. After the threads finish theircurrent task, before they go and grab a new task from they queue, they checkthe thread pools’m_bprocess bool, and if it’s false, they sit and waituntil the thread pool starts up again. Easy, but very important. Thesefunctions allow you to start the task processing when you’re ready to startprocessing. You could load up the thread pool with 3000 tasks and the threadswon’t touch one until BeginProcessing() is called.

Shutdown()

The shutdown is simple. Stop thethreads, clean the task memory, then clean the thread memory. not much else toit.

void KMThreadpool::Shutdown()
{
         KMTask* deltask;
         KMThread* delthread;
         // Stop the delegation of tasks
         if(m_bprocess != false)
         {
                  m_bprocess = false;
         }
         //Clear the threads
         while(!m_vthreads.empty())
         {
                  delthread = m_vthreads.back();
                  m_vthreads.pop_back();
                  delthread->End();
                  delete delthread;
         }
         //Clear the tasks
         while(!m_qtaskList.empty())
         {
                  //deltask = m_qtaskList.front();
                  deltask = m_qtaskList.pop();
                  delete deltask;
         }
}

AddTask()

This one is also pretty simple aswell. When you pass in a function pointer and a pointer to a child ofIKMTaskData, this function puts it into the KMTask container object, and addsit to the queue.

void KMThreadpool::AddTask(KMTaskFunc task, IKMTaskData* data)
{
         KMTask* newTask = new KMTask(task,data);
         m_qtaskList.push(newTask);
}

There you have it. That prettymuch covers the thread pool. Congratulations!

转自:http://keithmaggio.wordpress.com/code/c-win32-thread-pool-manager/5-step3/