ACE_Reactor框架也可以用来处理Unix/Linux系统的信号;
在传统上,要在POSIX系统上处理信号,就要涉及到signal()系统函数,它需要一个信号数字值、信号处理函数;但是新版本的sigaction()更加灵活,要编写能在多种UNIX系统平台上正常运行的信号处理代码,会比较麻烦,因为各种不同的UNIX系统平台上对这些函数的实现不尽相同;
ACE向我们提供了漂亮、干净的信号处理API,可在多种操作系统平台上使用:使用Reactor框架处理信号;首先从ACE_Event_Handler类派生出一个子类,并实现它的方法handle_signal(),在这个方法中编写信号处理代码;然后,通过两个适当的register_handler()方法中的一个来登记信号事件处理器(新派生出来的类的对象);
处理信号的Reactor框架一旦启动起来,当捕捉到信号的时候,信号处理器对象的handle_signal()方法就会被Reactor框架回调,以响应信号的动作;
例如:
class LoopStopper: public ACE_Event_Handler
{
public:
LoopStopper(int signum = SIGINT)
{
ACE_Reactor::instance()->register_handler(signum, this);
}
virtual int handle_signal(int signum, siginfo_t* = 0, ucontext_t* = 0)
{
ACE_Reactor::instance()->end_reactor_event_loop();
return 0;
}
};
一个事件处理器可以处理多个信号;在登记信号处理器的时候,不仅可以调用register_handler()方法每次为一个信号登记一个处理器,也可以调用另外一个重载的register_handler()方法为一组信号登记同一个信号处理器;这一组信号可以使用ACE_Sig_Set类来表示;
例如:
class LogSwitcher: public ACE_Event_Handler
{
private:
int on_sig_;
int off_sig_;
int on_off_;
private:
LogSwitcher(){};
public:
LogSwitcher(int on_sig, int off_sig): on_sig_(on_sig), off_sig_(off_sig)
{
ACE_Sig_Set sigs;
sigs.sig_add(on_sig);
sigs.sig_add(off_sig);
ACE_Reactor::instance()->register_handler(sigs, this);
}
virtual int handle_signal(int signum, siginfo_t* = 0, ucontext_t* = 0);
virtual int handle_exception(ACE_HANDLE fd = ACE_INVALID_HANDLE);
};
这个处理器类就可以处理多个信号了;
ACE_Sig_Set类除了sig_add()方法之外,还有一下方法:
sig_del(): 从信号集中移除某个信号;
is_member(): 判断某个信号是否在当前信号集中;
empty_set(): 从信号集中移除所有信号;
fill_set(): 用所有已知的信号填充信号集;
信号的通知功能:(通知事件)
我们可以在handle_signal()回调方法中调用ACE_Reactor::instance()->notify(ACE_Event_Handler*)回调方法;来通知信号处理器做某件事情;信号处理器回调方法notify()指向的是信号处理器自己的另外一个回调方法handle_exception();所以实现了handle_exception()之后,再调用notify()方法通知信号处理器的时候,就可以处理信号的通知事件;
评论