在ACE 6.0.0 里提供了一个Reactor示例程序,对其分析一下(在代码的注释里)。
Reactors_Test.cpp文件(在 \ACE-6.0.0\ACE_wrappers\tests\ 目录下):
// $Id: Reactors_Test.cpp 91671 2010-09-08 18:39:23Z johnnyw $ // ============================================================================ // // = LIBRARY // tests // // = FILENAME // Reactors_Test.cpp // // = DESCRIPTION // This is a test that performs a torture test of multiple // <ACE_Reactors> and <ACE_Tasks> in the same process. // // = AUTHOR // Prashant Jain <[email protected]>, // Detlef Becker <[email protected]>, and // Douglas C. Schmidt <[email protected]> // // ============================================================================ #include "test_config.h" #include "ace/Task.h" #include "ace/Reactor.h" #include "ace/Atomic_Op.h" #include "ace/Recursive_Thread_Mutex.h" #if defined (ACE_HAS_THREADS) ACE_Thread_Manager *thr_mgr; static const int MAX_TASKS = 20; class Test_Task : public ACE_Task<ACE_MT_SYNCH> // = TITLE // Exercise the tasks. { public: // = Initialization and termination methods. Test_Task (void); ~Test_Task (void); //FUZZ: disable check_for_lack_ACE_OS // = Task hooks. virtual int open (void *args = 0); virtual int close (u_long flags = 0); virtual int svc (void); //FUZZ: enable check_for_lack_ACE_OS // = Event Handler hooks. virtual int handle_input (ACE_HANDLE handle); virtual int handle_close (ACE_HANDLE fd, ACE_Reactor_Mask close_mask); private: size_t handled_; // Number of iterations handled. static int task_count_; // Number of tasks running. }; // Static data member initialization. int Test_Task::task_count_ = 0; static ACE_Atomic_Op<ACE_Thread_Mutex, int> done_count = MAX_TASKS * 2; static ACE_Recursive_Thread_Mutex recursive_lock; Test_Task::Test_Task (void) : handled_ (0) { ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock); Test_Task::task_count_++; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) TT+ Test_Task::task_count_ = %d\n"), Test_Task::task_count_)); } Test_Task::~Test_Task (void) { ACE_GUARD (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) TT- Test_Task::task_count_ = %d\n"), Test_Task::task_count_)); ACE_ASSERT (Test_Task::task_count_ == 0); } int Test_Task::open (void *args) { this->reactor (reinterpret_cast<ACE_Reactor *> (args)); return this->activate (THR_NEW_LWP); // 只有调用了activate方法后,才能自动执行后面的svc方法。 } int Test_Task::close (u_long) { ACE_GUARD_RETURN (ACE_Recursive_Thread_Mutex, ace_mon, recursive_lock, -1); Test_Task::task_count_--; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) close Test_Task::task_count_ = %d\n"), Test_Task::task_count_)); ACE_ASSERT (Test_Task::task_count_ >= 0); return 0; } int Test_Task::svc (void) // 在上面调用了activate方法后,任务自动执行svc方法。 { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) svc\n"))); for (size_t i = 0; i < ACE_MAX_ITERATIONS; i++) { ACE_OS::thr_yield (); // Only wait up to 10 milliseconds to notify the Reactor. ACE_Time_Value timeout (0, 10 * 1000); // 调用 Reactor 的 notify 方法向 Reactor 发送通知,后面的 handle_input 和 handle_close 方法在 Reactor 处理通知(在下面)时被回调。 if (this->reactor ()->notify (this, ACE_Event_Handler::READ_MASK, &timeout) == -1) { if (errno == ETIME) ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("notify() timed out"))); else ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("notify")), -1); } } return 0; } int Test_Task::handle_close (ACE_HANDLE, ACE_Reactor_Mask) { return 0; } int Test_Task::handle_input (ACE_HANDLE) { this->handled_++; if (this->handled_ == ACE_MAX_ITERATIONS) { done_count--; ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) handle_input, handled_ = %d, done_count = %d\n"), this->handled_, done_count.value ())); } ACE_OS::thr_yield (); return -1; } static void * worker (void *args) { ACE_Reactor *reactor = reinterpret_cast<ACE_Reactor *> (args); // Make this thread the owner of the Reactor's event loop. reactor->owner (ACE_Thread::self ()); // Use a timeout to inform the Reactor when to shutdown. ACE_Time_Value timeout (4); for (;;) switch (reactor->handle_events (timeout)) // 调用 Reactor 的 handle_events 方法,循环处理任务发来的通知(在上面),回调任务的 handle_input 和 handle_close 方法。 { case -1: ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("(%t) %p\n"), ACE_TEXT ("reactor")), 0); /* NOTREACHED */ case 0: ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) Reactor shutdown\n"))); return 0; } ACE_NOTREACHED (return 0); } #endif /* ACE_HAS_THREADS */ int run_main (int, ACE_TCHAR *[]) { ACE_START_TEST (ACE_TEXT ("Reactors_Test")); #if defined (ACE_HAS_THREADS) ACE_ASSERT (ACE_LOG_MSG->op_status () != -1); thr_mgr = ACE_Thread_Manager::instance (); ACE_Reactor reactor; ACE_ASSERT (ACE_LOG_MSG->op_status () != -1); Test_Task tt1[MAX_TASKS]; Test_Task tt2[MAX_TASKS]; // Activate all of the Tasks. for (int i = 0; i < MAX_TASKS; i++) { tt1[i].open (ACE_Reactor::instance ()); // 给任务关联Reactor。 tt2[i].open (&reactor); // 给任务关联Reactor。 } //创建两线程,分别监视两个Reactor。 // Spawn two threads each running a different reactor. if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (worker), (void *) ACE_Reactor::instance (), THR_BOUND | THR_DETACHED) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn")), -1); else if (ACE_Thread_Manager::instance ()->spawn (ACE_THR_FUNC (worker), (void *) &reactor, THR_BOUND | THR_DETACHED) == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("spawn")), -1); // 等待所有线程结束。 if (ACE_Thread_Manager::instance ()->wait () == -1) ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("wait")), -1); ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("(%t) all threads are finished\n"))); #else ACE_ERROR ((LM_INFO, ACE_TEXT ("threads not supported on this platform\n"))); #endif /* ACE_HAS_THREADS */ ACE_END_TEST; return 0; }
在run_main函数里写上下面输出语句,看看 ACE_Reactor::instance() 和 &reactor 是否相等。
printf("ACE_Reactor::instance() = %d, &reactor = %d, reactor.instance() = %d\n", ACE_Reactor::instance(), &reactor, reactor.instance());
运行发现:ACE_Reactor::instance() 和 reactor.instance() 相等,但与 &reactor 不相等。
查看ACE源代码,得知应该是下面原因。
ACE_Reactor 类里有 reactor_ 静态成员:
/// Pointer to a process-wide ACE_Reactor singleton.(指向一个进程内的ACE_Reactor单例)
static ACE_Reactor *reactor_;
但ACE_Reactor的构造函数里并没有对 reactor_ 如下赋值:
reactor_ = this;
所以 ACE_Reactor reactor; 语句没有把 &reactor 传入类中。