用ACE写得一个半同步半异步线程池模板。
//------------------------------------------ACE_ThreadPool.h-----------------------------------------------------/
#pragma once
#include <ace/Synch.h>
#include <ace/Task.h>
#include <ace/Synch.h>
#include <ace/Task.h>
//class ACE_Pool_Worker ;
class IManager
{
public:
virtual int Return2Work(void *) = 0;
};
{
public:
virtual int Return2Work(void *) = 0;
};
/************************************************************************/
/*the thread pool worker, it will process the data that from the message queue
user must derived this class to implement the interface process_message()
to process the data
author:lanhuaiyu@20060317
/************************************************************************/
class ACE_Pool_Worker : public ACE_Task<ACE_MT_SYNCH>
{
public:
ACE_Pool_Worker(IManager *pManager);
~ACE_Pool_Worker();
int svc();
ACE_thread_t ThreadID(){
return m_threadID;
}
protected:
virtual void process_message(ACE_Message_Block *pmb) = 0;
//this method will run before the thread start process the send
virtual int after_construct(){ return 0;};
virtual int before_destruct(){ return 0;}
IManager *m_pManager;
ACE_thread_t m_threadID;
};
/*the thread pool worker, it will process the data that from the message queue
user must derived this class to implement the interface process_message()
to process the data
author:lanhuaiyu@20060317
/************************************************************************/
class ACE_Pool_Worker : public ACE_Task<ACE_MT_SYNCH>
{
public:
ACE_Pool_Worker(IManager *pManager);
~ACE_Pool_Worker();
int svc();
ACE_thread_t ThreadID(){
return m_threadID;
}
protected:
virtual void process_message(ACE_Message_Block *pmb) = 0;
//this method will run before the thread start process the send
virtual int after_construct(){ return 0;};
virtual int before_destruct(){ return 0;}
IManager *m_pManager;
ACE_thread_t m_threadID;
};
/************************************************************************/
/* the template for create the thread pool and manage it */
/************************************************************************/
template<typename T>
class ACE_ThreadPool :
public ACE_Task<ACE_MT_SYNCH>, public IManager
{
public:
ACE_ThreadPool(size_t nPoolSize = 5);
~ACE_ThreadPool();
bool IsStopped();
void ShutDown();
virtual int svc();
virtual int Return2Work(void *);
private:
int CreatePool();
int DestroyPool();
size_t m_nPoolSize;
bool m_bShutDown;
/* the template for create the thread pool and manage it */
/************************************************************************/
template<typename T>
class ACE_ThreadPool :
public ACE_Task<ACE_MT_SYNCH>, public IManager
{
public:
ACE_ThreadPool(size_t nPoolSize = 5);
~ACE_ThreadPool();
bool IsStopped();
void ShutDown();
virtual int svc();
virtual int Return2Work(void *);
private:
int CreatePool();
int DestroyPool();
size_t m_nPoolSize;
bool m_bShutDown;
typedef ACE_Guard<ACE_Thread_Mutex> LOCK;
//lock for the stop flag
ACE_Thread_Mutex m_lockStop;
//lock for the stop flag
ACE_Thread_Mutex m_lockStop;
//lock for the threads queue
ACE_Thread_Mutex m_lockWork;
ACE_Condition<ACE_Thread_Mutex> m_condWork;
//the threads queue
ACE_Unbounded_Queue<T* > m_queTs;
};
ACE_Thread_Mutex m_lockWork;
ACE_Condition<ACE_Thread_Mutex> m_condWork;
//the threads queue
ACE_Unbounded_Queue<T* > m_queTs;
};
template<typename T>
ACE_ThreadPool<typename T>::ACE_ThreadPool(size_t nPoolSize)
: m_nPoolSize(nPoolSize),m_lockWork(), m_condWork(m_lockWork),m_bShutDown(false)
{
ACE_ThreadPool<typename T>::ACE_ThreadPool(size_t nPoolSize)
: m_nPoolSize(nPoolSize),m_lockWork(), m_condWork(m_lockWork),m_bShutDown(false)
{
}
template<typename T>
ACE_ThreadPool<typename T>::~ACE_ThreadPool()
{
ACE_ThreadPool<typename T>::~ACE_ThreadPool()
{
}
/************************************************************************/
/* shut down the current thread the pool, it only set the stop flag */
/************************************************************************/
template<typename T>
void ACE_ThreadPool<typename T>::ShutDown()
{
LOCK lock(this->m_lockStop);
m_bShutDown = true;
}
/* shut down the current thread the pool, it only set the stop flag */
/************************************************************************/
template<typename T>
void ACE_ThreadPool<typename T>::ShutDown()
{
LOCK lock(this->m_lockStop);
m_bShutDown = true;
}
/************************************************************************/
/* judge whether the stop flag status of current thread pool */
/************************************************************************/
template<typename T>
bool ACE_ThreadPool<typename T>::IsStopped()
{
LOCK lock(this->m_lockStop);
return m_bShutDown;
}
/* judge whether the stop flag status of current thread pool */
/************************************************************************/
template<typename T>
bool ACE_ThreadPool<typename T>::IsStopped()
{
LOCK lock(this->m_lockStop);
return m_bShutDown;
}
/************************************************************************/
/* create the pool according to the user requirement */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::CreatePool()
{
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
for (size_t i = 0; i < this->m_nPoolSize; i++)
{
T *worker;
ACE_NEW_RETURN (worker, T (this), -1);
this->m_queTs.enqueue_tail (worker);
worker->activate ();
}
return 0;
}
/* create the pool according to the user requirement */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::CreatePool()
{
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
for (size_t i = 0; i < this->m_nPoolSize; i++)
{
T *worker;
ACE_NEW_RETURN (worker, T (this), -1);
this->m_queTs.enqueue_tail (worker);
worker->activate ();
}
return 0;
}
/************************************************************************/
/* destroy the thread pool, it will destroy all of the threads */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::DestroyPool()
{
ACE_TRACE (ACE_TEXT ("ACE_ThreadPool::DestroyPool"));
ACE_Unbounded_Queue<T* >::ITERATOR iter =
this->m_queTs.begin ();
T **worker_ptr = NULL;
do
{
iter.next (worker_ptr);
T *worker = (*worker_ptr);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Attempting shutdown of %d/n"),
worker->ThreadID()));
/* destroy the thread pool, it will destroy all of the threads */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::DestroyPool()
{
ACE_TRACE (ACE_TEXT ("ACE_ThreadPool::DestroyPool"));
ACE_Unbounded_Queue<T* >::ITERATOR iter =
this->m_queTs.begin ();
T **worker_ptr = NULL;
do
{
iter.next (worker_ptr);
T *worker = (*worker_ptr);
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Attempting shutdown of %d/n"),
worker->ThreadID()));
// Send the hangup message.
ACE_Message_Block *mb;
ACE_NEW_RETURN
(mb,
ACE_Message_Block(0,
ACE_Message_Block::MB_HANGUP),
-1);
worker->putq (mb);
ACE_Message_Block *mb;
ACE_NEW_RETURN
(mb,
ACE_Message_Block(0,
ACE_Message_Block::MB_HANGUP),
-1);
worker->putq (mb);
// Wait for the exit.
worker->wait ();
worker->wait ();
ACE_ASSERT (worker->msg_queue ()->is_empty ());
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Worker %d shut down./n)"),
worker->ThreadID()));
delete worker;
}
while (iter.advance ());
ACE_DEBUG ((LM_DEBUG,
ACE_TEXT ("(%t) Worker %d shut down./n)"),
worker->ThreadID()));
delete worker;
}
while (iter.advance ());
return 0;
}
}
template<typename T>
int ACE_ThreadPool<typename T>::svc()
{
ACE_TRACE(ACE_TEXT ("ACE_ThreadPool::svc"));
int ACE_ThreadPool<typename T>::svc()
{
ACE_TRACE(ACE_TEXT ("ACE_ThreadPool::svc"));
ACE_DEBUG((LM_INFO, ACE_TEXT ("(%t) ACE_ThreadPool started/n")));
// Create pool.
CreatePool();
CreatePool();
while (!IsStopped())
{
ACE_Message_Block *mb = NULL;
/*ACE_Time_Value tv ((long)REQ_DELAY);
tv += (long)ACE_OS::time (0);*/
{
ACE_Message_Block *mb = NULL;
/*ACE_Time_Value tv ((long)REQ_DELAY);
tv += (long)ACE_OS::time (0);*/
// Get a message request.
if (this->getq (mb) < 0)
{
//shut_down ();
break;
}
if (this->getq (mb) < 0)
{
//shut_down ();
break;
}
// Choose a worker.
T *worker;
{
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
T *worker;
{
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
while (this->m_queTs.is_empty ())
m_condWork.wait ();
m_condWork.wait ();
this->m_queTs.dequeue_head (worker);
}
}
// Ask the worker to do the job.
worker->putq (mb);
}
worker->putq (mb);
}
DestroyPool();
ACE_DEBUG((LM_DEBUG, "(%P | %t) ACE_ThreadPool will exit!!!"));
return 0;
return 0;
}
/************************************************************************/
/* call back method of the work thread */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::Return2Work(void *worker)
{
ACE_ASSERT(worker != NULL);
T * pWork = ACE_static_cast(T*, worker);
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
//ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Worker %d returning to work./n"), pWork->thr_mgr ()->thr_self ()));
this->m_queTs.enqueue_tail (pWork);
this->m_condWork.signal ();
return 0;
}
/* call back method of the work thread */
/************************************************************************/
template<typename T>
int ACE_ThreadPool<typename T>::Return2Work(void *worker)
{
ACE_ASSERT(worker != NULL);
T * pWork = ACE_static_cast(T*, worker);
ACE_GUARD_RETURN (ACE_Thread_Mutex,
worker_mon, this->m_lockWork, -1);
//ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Worker %d returning to work./n"), pWork->thr_mgr ()->thr_self ()));
this->m_queTs.enqueue_tail (pWork);
this->m_condWork.signal ();
return 0;
}
//-----------------------ACE_ThreadPool.cpp--------------------------------------------------------------------------//
#include <stdafx.h>
#include "ACE_ThreadPool.h"
ACE_Pool_Worker::ACE_Pool_Worker(IManager *pManager) : m_pManager(pManager)
{
}
ACE_Pool_Worker::~ACE_Pool_Worker()
{
//user destroy the data or handle
before_destruct();
}
{
//user destroy the data or handle
before_destruct();
}
/************************************************************************/
/* the thread run method , it will get the message from the */
/************************************************************************/
int ACE_Pool_Worker::svc()
{
ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) ACE_Pool_Worker started/n")));
//call it ,the user can process it according to the user's requirement,
//for example, connect to server
after_construct();
/* the thread run method , it will get the message from the */
/************************************************************************/
int ACE_Pool_Worker::svc()
{
ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) ACE_Pool_Worker started/n")));
//call it ,the user can process it according to the user's requirement,
//for example, connect to server
after_construct();
m_threadID = ACE_Thread::self ();
while (true)
{
ACE_Message_Block *mb = NULL;
ACE_ASSERT (this->getq (mb) != -1);
if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) Shutting down/n")));
mb->release ();
break;
}
while (true)
{
ACE_Message_Block *mb = NULL;
ACE_ASSERT (this->getq (mb) != -1);
if (mb->msg_type () == ACE_Message_Block::MB_HANGUP)
{
ACE_DEBUG ((LM_INFO,
ACE_TEXT ("(%t) Shutting down/n")));
mb->release ();
break;
}
// Process the message.
process_message (mb);
process_message (mb);
// Return to work.
this->m_pManager->return_to_work (this);
}
this->m_pManager->return_to_work (this);
}