Chinaunix首页 | 论坛 | 博客
  • 博客访问: 76302
  • 博文数量: 47
  • 博客积分: 1400
  • 博客等级: 上尉
  • 技术积分: 560
  • 用 户 组: 普通用户
  • 注册时间: 2009-01-12 18:04
文章分类

全部博文(47)

文章存档

2010年(7)

2009年(40)

我的朋友

分类:

2009-01-19 23:18:01

ace 组件学习(一)

信号处理组件的设计

1. 问题
   传统信号处理流程
   1) 定义各待捕获信号的处理函数
   2) 定义全局变量
   3) 传统的信号底层信号注册api

代码:
    /* Global variables that control
       process shutdown. */
    sig_atomic_t graceful_quit = 0;
    sig_atomic_t abortive_quit = 0;
    
    /* Signal handler for SIGINT. */
    void SIGINT_handler (int signum)
    {
      assert (signum == SIGINT);
      graceful_quit = 1;
    }
    
    /* Signal handler for SIGQUIT. */
    void SIGQUIT_handler (int signum)
    {
      assert (signum == SIGQUIT);
      abortive_quit = 1;
    }
    
    /* ... */
    
    int main (void)
    {
      struct sigaction sa;
      sigemptyset (&sa.sa_mask);
      sa.sa_flags = 0;
    
      /* Register the handler for SIGINT. */
      sa.sa_handler = SIGINT_handler;
      sigaction (SIGINT, &sa, 0);
    
      /* Register the handler for SIGQUIT. */
      sa.sa_handler =  SIGQUIT_handler;
      sigaction (SIGQUIT, &sa, 0);
    
      /* Run the main event loop. */
      while (graceful_quit == 0
             && abortive_quit == 0)
        do_work ();
    
      if (abortive_quit == 1) {
        _exit (1);
      }
      else if graceful_quit {
        clean_up ();
        exit (0);
      }
    
      /* NOTREACHED */
    }


2. 设计模式
  1) singleton pattern
  2) adapter pattern
  3) hook method pattern
 
3. 代码实现
    
  1) 定义回调接口 hook method pattern
   class Event_Handler
  {
  public:
    // Hook method for the signal hook method.
    virtual int handle_signal (int signum) = 0;
  
    // ... other hook methods for other types of
    // events such as timers, I/O, and
    // synchronization objects.
  };
  
   2). 将信号处理组件(signal handler)作为一个单件使用 singleton pattern
     class Signal_Handler
   {
   public:
    // Entry point.
    static Signal_Handler *instance (void);
   
    // Register an event handler for
    // and return a pointer to any existing
    // that was previously registered to handle .
    Event_Handler *register_handler (int signum,
                       Event_Handler *eh);
   
    // Remove the for
    // by setting the slot in the
    // table to NULL.
    int remove_handler (int signum);
   
   private:
    // Ensure we're a Singleton.
    Signal_Handler (void);
   
    // Singleton pointer.
    static Signal_Handler *instance_;
   
    // Entry point adapter installed into
    // (must be a static method or a stand-alone
    // extern "C" function).
    static void dispatcher (int signum);
   
    // Table of pointers to concrete s
    // registered by applications.  NSIG is the number of
    // signals defined in .
    static Event_Handler *signal_handlers_[NSIG];
   };


    3) 将dispatcher适配成系统注册回调的接口,通过它进行信号到事件的派发。
   
    void Signal_Handler::dispatcher (int signum)
  {
    // Perform a sanity check...
    if (Signal_handler::signal_handlers_[signum] != 0)
      // Dispatch the handler's hook method.
      Signal_handler::signal_handlers_
        [signum]->handle_signal (signum);
  }
 


 4. 组件小结
 
    ACE信号组件不仅仅提供的是一个Signal_Handler信号处理组件,同时ACE将
    struct sigaction 结构进行wrapper模式的包装,用户可以直接通过
    ACE_Sig_Action包装类来进行信号的注册,不过该包装类仅仅是一个sigaction
    对象的封装以及注册,注册的回调还必须是系统定义的原型
    void func(int);
    ACE将该原型进行了重定义:
    typedef void (*ACE_SignalHandler)(int);
   
5. 信号组件的使用技巧
  通过 ACE_Sig_Action 对象注册修改一些系统默认的信号操作。
  通过 Signal_Handler 对象注册用户自定义的信号操作。
  两者结合使用。

6. 代码
#include
using namespace std;

#include
//定义事件处理回调
class sig_INT: public ACE_Event_Handler
{
public:
    int handle_signal (int signum, siginfo_t *, ucontext_t *);
};

int g_stop = 0;

int sig_INT::handle_signal(int signum, siginfo_t * info, ucontext_t * context)
{
    cout<<"INT SIGNAL Catched"<    //g_stop = 1;
    return 0;
}

int main()
{
    //修改系统默认信号处理
    ACE_Sig_Action sig_handler_ignore((ACE_SignalHandler)SIG_IGN);
    sig_handler_ignore.register_action(SIGQUIT);
    sig_handler_ignore.register_action(SIGCLD);
   
    //设置用户自定义信号处理
    ACE_Sig_Handler sig_handler;
    sig_INT int_ev;
    sig_handler.register_handler(SIGINT, &int_ev);
   
    int count = 0;
    while(!g_stop)
    {
        sleep(10);
        count++;
       
        cout<<"zzzz..."<        if(count >= 5) break;
    }
    return 0;
}


阅读(664) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~