// 头文件 class Svc_Thread_Pool : public ACE_Task_Base { public: enum { DEFAULT_POOL_SIZE = 8, MAX_TIMEOUT = 5, }; Svc_Thread_Pool (); ~Svc_Thread_Pool (); int open (int pool_size = DEFAULT_POOL_SIZE); virtual int open (void *args) { return ACE_Task_Base::open(args); }; int svc (); int add_to_pool (ACE_Task_Base * tb); bool done () { return (_shutdown == 0) ? false : true; }; void shutdown (); protected: ACE_Thread_Mutex _workers_lock; ACE_Condition<ACE_Thread_Mutex> _cond; std::queue<ACE_Task_Base *> _workers_queue; ACE_Atomic_Op<ACE_Thread_Mutex, int> _shutdown; }; // ------------------------------------------------------------------------------------------------------------------------ // 实现 Svc_Thread_Pool::Svc_Thread_Pool () : ACE_Task_Base(ACE_Thread_Manager::instance ()), _workers_lock(), //_cond_lock(), _cond (/*_cond_lock*/_workers_lock), _shutdown (0) { } // ------------------------------------------------------------------------------------------------------------------------ Svc_Thread_Pool::~Svc_Thread_Pool () { } // ------------------------------------------------------------------------------------------------------------------------ int Svc_Thread_Pool::open (int pool_size) { return activate (THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED, pool_size); } // ------------------------------------------------------------------------------------------------------------------------ int Svc_Thread_Pool::svc () { ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Svc_Thread_Pool svc() started /n"))); while (!done ()) { // 锁定队列并获取一个 ACE_Task_Base *。 ACE_Task_Base * tb = 0; assert (_workers_lock.acquire () == 0); if (_workers_queue.size () != 0) { tb = _workers_queue.front (); _workers_queue.pop (); // 解锁 队列 assert (_workers_lock.release () == 0); // 执行 ACE_Task_Base::svc () if (tb) { // svc 中应该自己解决自己数据的同步问题。并且自己加入 Svc_Thread_Pool 中 // ACE_Task_Base 应该自己保存 Svc_Thread_Pool 的对象指针。 tb->svc (); } } else { // 解锁 队列 assert (_cond.wait () == 0); assert (_workers_lock.release () == 0); ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Svc_Thread_Pool recv msg /n"))); } } ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t) Svc_Thread_Pool svc() end !!/n"))); return 0; } // ------------------------------------------------------------------------------------------------------------------------ int Svc_Thread_Pool::add_to_pool (ACE_Task_Base * tb) { if (_shutdown != 0) { return -1; } // 锁定队列,并加入工作者线程 assert (_workers_lock.acquire () == 0); _workers_queue.push (tb); // 通知 assert (_cond.signal () == 0); // 解锁队列 assert (_workers_lock.release () == 0); printf ("add_to_pool/n"); return 0; } // ------------------------------------------------------------------------------------------------------------------------ void Svc_Thread_Pool::shutdown () { _shutdown = 1; assert (_workers_lock.acquire () == 0); // lock queue while (_workers_queue.size () != 0) { _workers_queue.pop (); } assert (_cond.broadcast () == 0); assert (_workers_lock.release () == 0); // unlock queue ACE_DEBUG ((LM_INFO, ACE_TEXT ("(%t)broadcast/n"))); //assert (_workers_lock.acquire () == 0); //assert (_cond.broadcast () == 0); //assert (_workers_lock.release () == 0); this->wait(); printf ("shutdown/n"); } // ------------------------------------------------------------------------------------------------------------------------ // 测试! #include "../cmn/extend_ace/Svc_Thread_Pool.h" Svc_Thread_Pool tp; class My_Task : public ACE_Task_Base { public: My_Task () { j = i ++; } int svc () { // 先锁定 handle_close ().禁止svc的时候被reactor handle_close (),或者禁止调用handle_close,让他在svc中自己调用。 // lock //ACE_OS::sleep (0); printf ("%d: thread: %d/n", j, ACE_Thread::self ()); //tp.add_to_pool (this); return 0; // unlock } static int i; int j; }; int My_Task::i = 0; int test () { tp.open (8); ACE_OS::sleep (3); My_Task mt1, mt2, mt3, mt4, mt5, mt6, mt7, mt8, mt9, mt10; tp.add_to_pool (&mt1); tp.add_to_pool (&mt2); tp.add_to_pool (&mt3); tp.add_to_pool (&mt4); tp.add_to_pool (&mt5); tp.add_to_pool (&mt6); tp.add_to_pool (&mt7); tp.add_to_pool (&mt8); tp.add_to_pool (&mt9); tp.add_to_pool (&mt10); ACE_OS::sleep (6); tp.shutdown (); //ACE_OS::sleep (5); system ("pause"); return 0; }