ACE中的反应堆与若干内部和外部组件协同工作。其基本概念是反应堆构架检测事件的发生(通过在OS事件多路分离接口上进行侦听),并发出对预登记事件处理器(event handler)对象中的方法的“回调”(callback)。该方法由应用开发者实现,其中含有应用处理此事件的特定代码。于是用户(也就是,应用开发者)必须:
1.创建事件处理器,以处理他所感兴趣的某事件。
2.在反应堆上登记,通知说他有兴趣处理某事件,同时传递他想要用以处理此事件的事件处理器的指针给反应堆
。
随后反应堆构架将自动地:
1.在内部维护一些表,将不同的事件类型与事件处理器对象关联起来。
2.在用户已登记的某个事件发生时,反应堆发出对处理器中相应方法的回调。
ACE_Event_Handler类拥有若干不同的“handle”(处理)方法,每个处理方法被用于处理不同种类的事件。当应用程序员对特定事件感兴趣时,他就对ACE_Event_Handler类进行子类化,并实现他感兴趣的处理方法。如上面所提到的,随后他就在反应堆上为特定事件“登记”他的事件处理器类。于是反应堆就会保证在此事件发生时,自动回调在适当的事件处理器对象中的适当的"handle"方法.使用ACE_Reactor基本上有三个步骤:
1.创建ACE_Event_Handler的子类,并在其中实现适当的“handle_”方法,以处理你想要此事件处理器为之服务的事件类型。注意你可以使用同一个事件处理器对象处理多种类型的事件,因而可以重载多于一个的“handle_”方法。
2.通过调用反应堆对象的register_handler(),将你的事件处理器登记到反应堆。
3.在事件发生时,反应堆将自动回调相应的事件处理器对象的适当的“handle_”方法
。
#include <signal.h>
#include "ace/Reactor.h"
#include "ace/Event_Handler.h"
#include "ace/Log_Msg.h" //ace_debug
//Create our subclass to handle the signal events
//that we wish to handle. Since we know that this particular
//event handler is going to be using signals we only overload the
//handle_signal method.
class MyEventHandler: public ACE_Event_Handler
{
int handle_signal(int signum, siginfo_t*,ucontext_t*)
{
switch(signum)
{
case SIGBREAK://SIGWINCH:
ACE_DEBUG((LM_DEBUG, "You pressed KILL(SIGBREAK)\n"));
break;
case SIGINT:
ACE_DEBUG((LM_DEBUG, "You pressed SIGINT\n"));
break;
}
return 0;
}
};
int main(int argc, char *argv[])
{
//instantiate the handler
MyEventHandler *eh =new MyEventHandler;
//Register the handler asking to call back when either SIGBREAK
//or SIGINT signals occur. Note that in both the cases we asked the
//Reactor to callback the same Event_Handler i.e., MyEventHandler.
//This is the reason why we had to write a switch statement in the
//handle_signal() method above. Also note that the ACE_Reactor is
//being used as a Singleton object (Singleton pattern)
ACE_Reactor::instance()->register_handler(SIGBREAK,eh);//SIGWINCH,eh);
ACE_Reactor::instance()->register_handler(SIGINT,eh);
while(1)
//Start the reactors event loop
ACE_Reactor::instance()->handle_events();
}
ctrlC-exit.