找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 4711|回复: 5

Reactor事件的问题!

[复制链接]
发表于 2007-12-22 21:40:53 | 显示全部楼层 |阅读模式
我把ACE_Reactor::instance()->run_reactor_event_loop();  放在我的主线程中,我的定时器就正常!
如果我把ACE_Reactor::instance()->run_reactor_event_loop();放在子线程中,为什么我的定时器就不起作用了呢?
定时器也不会出错!!!
 楼主| 发表于 2007-12-22 21:41:23 | 显示全部楼层
//
// 这是测试代码!
//
  1. #include
  2. #include
  3. #include "ace/Task_T.h"
  4. #include "ace/Reactor.h"
  5. #include "ace/Event_Handler.h"
  6. class A : public ACE_Task
  7. {
  8. public:
  9. int svc(void)
  10. {
  11.   while(ACE_Reactor::instance()->reactor_event_loop_done() == 0)
  12.    ACE_Reactor::instance()->run_reactor_event_loop();
  13.   return 0;
  14. }
  15. int stop(void)
  16. {
  17.   ACE_Reactor::instance()->end_reactor_event_loop();
  18.   return 0;
  19. }
  20. int start(int nThread = 1)
  21. {
  22.   this->activate(THR_NEW_LWP|THR_JOINABLE|THR_INHERIT_SCHED, nThread);
  23.   return 0;
  24. }
  25. };
  26. class B : public ACE_Event_Handler
  27. {
  28. public:
  29.    virtual int handle_timeout (const ACE_Time_Value ¤t_time,
  30.                               const void *act = 0)
  31.    {
  32.     ACE_DEBUG((LM_DEBUG, "..................\n"));
  33.     return 0;
  34.    }
  35. };
  36. int ACE_TMAIN(int argc, ACE_TCHAR *argv[])
  37. {
  38. A a;
  39. B b;
  40. a.start();
  41. ACE_Time_Value const timeout(3);
  42. if (ACE_Reactor::instance()->schedule_timer(&b, 0, timeout, timeout) == -1)
  43.   ACE_ERROR((LM_ERROR, ACE_TEXT("(%t) %p\n"), ACE_TEXT("schedule_timer")));
  44. a.wait();  // 用这个,定时器就无效!
  45. //ACE_Reactor::instance()->run_reactor_event_loop();  // 用这个没有问题!正常!
  46. return 0;
  47. }
复制代码
 楼主| 发表于 2007-12-22 21:41:33 | 显示全部楼层
修改你的

int A::svc(void),增加

ACE_Reactor::instance()->owner(ACE_OS::self());
 楼主| 发表于 2007-12-22 21:42:00 | 显示全部楼层
补上完整的测试代码,VC2005/xp下通过
  1. /**
  2. test.cpp
  3. Stone jiang
  4. */
  5. #include "ace/OS_NS_time.h"
  6. #include "ace/Log_Msg.h"
  7. #include "ace/Reactor.h"
  8. #include "ace/Event_Handler.h"
  9. #include "ace/Task.h"
  10. #include "ace/Thread_Manager.h"
  11. #include "ace/TP_Reactor.h"
  12. #include "ace/WFMO_Reactor.h"
  13. class MyTimerHandler : public ACE_Event_Handler
  14. {
  15. public:
  16.     int handle_timeout (const ACE_Time_Value ¤t_time,
  17.         const void * = 0)
  18.     {
  19.         time_t epoch = ((timespec_t)current_time).tv_sec;
  20.         ACE_DEBUG ((LM_INFO,
  21.             ACE_TEXT ("(%t) handle_timeout: %s\n"),
  22.             ACE_OS::ctime (&epoch)));
  23.         return 0;
  24.     }
  25. };
  26. class SigintHandler : public ACE_Event_Handler
  27. {
  28. public:
  29.     int handle_signal (int signum, siginfo_t * = 0,
  30.         ucontext_t * = 0)
  31.     {
  32.         if (signum == SIGINT)
  33.         {
  34.             ACE_Reactor::instance ()->end_reactor_event_loop ();
  35.         }
  36.         return 0;
  37.     }
  38. };
  39. class ReactorThread :public ACE_Task
  40. {
  41. public:
  42.     ReactorThread(void* r)
  43.     {
  44.         reactor_ = (ACE_Reactor*) r;
  45.         ACE_DEBUG ((LM_INFO,
  46.             ACE_TEXT ("ReactorThread::ReactorThread()\n")));
  47.         this->activate(THR_NEW_LWP | THR_JOINABLE | THR_INHERIT_SCHED,3);
  48.     }
  49.     virtual int svc()
  50.     {
  51.         ACE_DEBUG ((LM_INFO,
  52.             ACE_TEXT (" (%t) ReactorThread::svc()\n")));
  53.            reactor_->owner (ACE_OS::thr_self ());
  54.            reactor_->run_reactor_event_loop();
  55.            return 0;
  56.     }
  57. private:
  58.    ACE_Reactor* reactor_;
  59. };
  60. int ACE_TMAIN (int, ACE_TCHAR *[])
  61. {
  62.       
  63.     ACE_DEBUG ((LM_INFO,
  64.         ACE_TEXT ("(%t) main::start \n")));
  65.     ACE_WFMO_Reactor this_reactor;
  66.     ACE_Reactor reactor (&this_reactor);
  67.     auto_ptr delete_instance
  68.     (ACE_Reactor::instance (&reactor));
  69.     ReactorThread thread(ACE_Reactor::instance());
  70.     MyTimerHandler * timer = new MyTimerHandler ();
  71.     ACE_Time_Value initialDelay (1);
  72.     ACE_Time_Value interval (2);
  73.     ACE_Reactor::instance()->schedule_timer (timer,
  74.         0,
  75.         initialDelay,
  76.         interval);
  77.    
  78.     SigintHandler * handleExit = new SigintHandler ();
  79.     ACE_Reactor::instance()->register_handler (SIGINT,
  80.         handleExit);
  81.   thread.wait();
  82.     ACE_DEBUG ((LM_INFO,
  83.         ACE_TEXT ("main::exit \n")));
  84.     return 0;
  85. }
复制代码
 楼主| 发表于 2007-12-22 21:42:15 | 显示全部楼层
stone正解,测试了一下,的确如此。
svc改成:
  while(ACE_Reactor::instance()->reactor_event_loop_done() == 0)
  {
   ACE_Reactor::instance()->owner(ACE_OS::thr_self ());
   ACE_Reactor::instance()->run_reactor_event_loop();
  }
即完全正常。

原因是:
set the owner of the reactor to the identity of the thread that runs the event loop
 楼主| 发表于 2007-12-22 21:42:52 | 显示全部楼层
The thread which is "owner" of the WFMO_Reactor. The owner
concept is used because we don't want multiple threads to try to
expire timers. Therefore the "owner" thread is the only one
allowed to expire timers. Also, the owner thread is the only
thread which waits on the notify handle. Note that the ownership
can be transferred.
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-11-23 15:30 , Processed in 0.015794 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表