ACE中的Reactor框架简介

原创 2006年10月25日 11:45:00

 

Joise.LI @ 2006-10-16
一、        概要
目前用于事件多路分离的OS抽象既复杂又难以使用,因而也容易出错。反应器本质上提供一组更高级的编程抽象,简化了事件驱动的分布式应用的设计和实现。除此而外,反应器还将若干不同种类的事件的多路分离集成到易于使用的API中。特别地,反应器对基于定时器的事件信号事件基于I/O端口监控的事件用户定义的通知进行统一地处理。
二、        使用
a)      如何使用:
首先应用开发者
1.     创建事件处理器,以处理他所感兴趣的某事件。
2.     在反应器上登记,通知说他有兴趣处理某事件,同时传递他想要用以处理此事件的事件处理器的指针给反应器。
然后反应器框架将自动地
1.     在内部维护一些表,将不同的事件类型与事件处理器对象关联起来。
2.       在用户已登记的某个事件发生时,反应器发出对处理器中相应方法的回调。
b)      基于定时器的事件简单示例:
#include <ace/Reactor.h>
#include <ace/Event_Handler.h>
 
#include <iostream>
using namespace std;
 
class timer_handler : public ACE_Event_Handler
{
public:
 virtual int handle_timeout (const ACE_Time_Value &current_time,const void *act = 0)
 {
       cout << "handle_timeout" << endl;
 
       return -1;
 }
 
 virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
 {
       cout << "handle_close" << endl;
 
       delete this;
 
       return 0;
 }
 
private:
 ~timer_handler()
 {
 
 }
};
 
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
 ACE_Time_Value time_(4);
 ACE_Reactor::instance()->schedule_timer(new timer_handler, NULL, time_, time_);
 
 while (true)
 {
       ACE_Reactor::instance()->handle_events();
 }
 
 return 0;
}
c)       基于信号事件的简单示例
#include <ace/Reactor.h>
#include <ace/Event_Handler.h>
 
#include <iostream>
using namespace std;
#include <signal.h>
 
class signal_handler : public ACE_Event_Handler
{
public:
     virtual int handle_signal(int signum, siginfo_t * /* = 0 */, ucontext_t * /* = 0 */)
     {
         cout << "signum = " << signum << endl;
 
         return 0;
     }
};
 
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
     signal_handler handler_;
     ACE_Reactor::instance()->register_handler(SIGBREAK, &handler_);
     ACE_Reactor::instance()->register_handler(SIGINT, &handler_);
 
     while (true)
     {
         ACE_Reactor::instance()->handle_events();
     }
 
     return 0;
}
d)      基于I/O端口监控事件的简单示例
#include <ace/INET_Addr.h>
#include <ace/SOCK_Acceptor.h>
#include <ace/SOCK_Stream.h>
class io_handler : public ACE_Event_Handler
{
public:
     virtual int handle_input(ACE_HANDLE fd /* = ACE_INVALID_HANDLE */)
     {
         cout << "handle_input" << endl;
 
         ACE_SOCK_Stream stream_;
         ACE_INET_Addr addr_;
         m_acceptor.accept(stream_, &addr_);
 
         stream_.send("joise", 6);
 
         return 0;
     }
 
     io_handler()
     {
         ACE_INET_Addr addr_(8004);
         m_acceptor.open(addr_);
     }
 
     virtual ACE_HANDLE get_handle() const
     {
         return m_acceptor.get_handle();
     }
private:
     ACE_SOCK_Acceptor m_acceptor;
};
 
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
     io_handler handler_;
     if (ACE_Reactor::instance()->register_handler(&handler_, ACE_Event_Handler::ACCEPT_MASK) != 0)
         cout << "register failed" << endl;
 
     while (ACE_Reactor::instance()->event_loop_done() == 0)
     {
         ACE_Reactor::instance()->handle_events();
     }
 
     return 0;
}
e)       基于用户定义的通知的简单示例
class notify_handler : public ACE_Event_Handler
{
public:
     virtual int handle_input(ACE_HANDLE fd /* = ACE_INVALID_HANDLE */)
     {
         cout << "handle_input" << endl;
 
         return 0;
     }
};
 
int ACE_TMAIN (int argc, ACE_TCHAR *argv[])
{
     notify_handler handler_;
     while (ACE_Reactor::instance()->event_loop_done() == 0)
     {
         ACE_Time_Value time_(4);
         ACE_Reactor::instance()->handle_events(time_);
         ACE_Reactor::instance()->notify(&handler_, ACE_Event_Handler::READ_MASK);
     }
 
     return 0;
}
 
f)         ACE_Event_Handler中提供以备继承的事件回调方法:
 

方法
在子类中重载,所处理事件的类型:
handle_signal()
信号。当任何在反应器上登记的信号发生时,反应器自动回调该方法。
handle_input()
来自I/O设备的输入。当I/O句柄(比如UNIX中的文件描述符)上的输入可用时,反应器自动回调该方法。
handle_exception()
异常事件。当已在反应器上登记的异常事件发生时(例如,如果收到SIGURG(紧急信号)),反应器自动回调该方法。
handle_timeout()
定时器。当任何已登记的定时器超时的时候,反应器自动回调该方法。
handle_output()
I/O设备输出。当I/O设备的输出队列有可用空间时,反应器自动回调该方法。
g)        在处理器上登记或删除某事件:register_handlerremove_handlerschedule_timer
 

掩码
回调方法
何时
和⋯⋯一起使用
ACE_Event_Handler::READ_MASK
handle_input()
在句柄上有数据可读时。
register_handler()
ACE_Event_Handler::WRITE_MASK
handle_output()
在I/O设备输出缓冲区上有可用空间、并且新数据可以发送给它时。
register_handler()
ACE_Event_Handler::TIMER_MASK
handle_close()
传给handle_close()以指示调用它的原因是超时。
接受器和连接器的handle_timeout方法。反应器不使用此掩码。
ACE_Event_Handler::ACCEPT_MASK
handle_input()
在OS内部的侦听队列上收到了客户的新连接请求时。
register_handler()
ACE_Event_Handler::CONNECT_MASK
handle_input()
对于非阻塞连接,在连接已经建立时。
register_handler()
ACE_Event_Handler::DONT_CALL
None.
在反应器的remove_handler()被调用时保证事件处理器的handle_close()方法不被调用。
remove_handler()
h)        生命期:
               i.静态管理事件处理器的生命期
在栈上声明一个事件处理器,静态管理其生命期,则
l         使用方法register_handler或schedule_timer将某事件登记到反应器上,其在反应器之上的生命期开始
l         使用方法remove_handler显式的将事件从反应器上移除,其在反应器之上的生命期结束,或
l         在事件处理器相应的handle_*方法被回调时返回-1,则框架会自动的为此事件处理器检测已登记的事件并且将其从反应器之上移除,在移除之前,会调用事件处理器的handle_close回调方法以清除资源,调用之后,其在反应器之上的生命期也结束。
             ii.动态管理事件处理器的生命期
由于上述静态管理事件处理器的生命期可能会导致对已经不存在的事件处理器进行分派的问题,所以一般使用动态管理事件器的生命期:
class dynamic_handler : public ACE_Event_Handler
{
private:
     ~dynamic_handler(){}
 
     ACE_Reactor_Mask m_mask;
 
public:
     virtual int handle_close(ACE_HANDLE handle, ACE_Reactor_Mask close_mask)
     {
         ACE_CLR_BITS(m_mask, close_mask);
 
         switch(close_mask)
         {
         case READ_MASK:
              ;// 执行read相关的清除逻辑
              break;
              ...
         }
 
         if (m_mask == 0)
              delete this;
     }
};
三、        实现
a)      框架类图
 
b)      ACE_Reactor类详解
初始化及清理:
                        i.              ACE_ReactorOpen:创建并初始化Reactor实例
                      ii.              ~ACE_ReactorClose:清理反应器在初始化时分配的资源
事件处理器的管理:
                    iii.              register_handler:登记事件处理器
                   iv.              remove_handler:移除事件处理器
                     v.              suspend_handler:暂停分派事件给事件处理器
                   vi.              resume_handler:恢复分派事件给事件处理器
                 vii.              mask_ops:获取、设计、增加或是清除与某事件处理器相关的事件类型及其掩码
               viii.              schedulee_wakeup:将指定的掩码增加到某事件处理器的条目中,该处理器在此之前必须已经通过register_handler作了登记
                   ix.              cancel_wakeup:从某事件处理器的条目中清除指定的掩码,但并不移除此处理器
事件的分派管理:
                     x.              handle_events:等待事件发生,并随即分派与之相关联的事件处理器。
                   xi.              run_event_loop:反复调用handle_events方法,直到其失败或是event_loop_done返回1,或是发生超时。
                 xii.              end_event_loop:指示反应器关闭事件循环
               xiii.              event_loop_done:在end_reactor_event_loop调用结束之后返回1
定时器管理:
               xiv.              schedule_timer:登记一个事件处理器,它将在用户规定的时间之后执行,相当于一个定时器
                 xv.              cancel_timer:取消一个或多个先前登记的定时器
通知管理:
               xvi.              notify:通知指定的事件处理器有某事件发生
             xvii.              max_notify_iterations:设置反应器在其通知机制中分派的处理器的最大数目
其它方法:
           xviii.              instance:提供对反应器单子模式的访问
c)       Reactor框架中,使用了Bridge模式来实现保持ACE_Reactor接口恒定而又可以扩展或增强其接口。下图是

        i.              ACE_Select_Reactor

ACE_Reactor接口的一种实现,使用select同步事件多路分离。
                     ii.              ACE_TP_Reactor
ACE_Reactor接口的另一种实现,可以让一“池”线程并发的调用handle_events,从而解决某些应用对于单线程调用handle_events的性能不够问题。
                  iii.              ACE_WFMO_Reactor
windows下的使用WaitForMultipleObjects函数来进行事件多路分离的一种实现。
                   iv.              。。。,还有一些其它的扩展的Reactor的实现。
四、        后记
ReactorACE框架中的基础框架,Acceptor-ConnectorProactor是依赖于Reactor的框架。
五、             作者相关信息:
欢迎大家与我交流,共同学习,共同提高。
joise@126.com,
http://joise.126.com
 

用ACE的Reactor模式实现网络通讯的例子

用ACE的Reactor模式实现网络通讯的例子,不罗嗦,直接上代码
  • iw1210
  • iw1210
  • 2014年07月01日 19:42
  • 3293

基于ACE框架---C++多线程开发总结1,涉及 互斥量、读写锁、条件锁、基于条件锁的线程流水控制

本文对ACE使用的介绍不多,因网上ACE的资料很多,故不进行介绍,而仅使用 当使用多线程进行开发工作的时候,必然会涉及到对公有数据的读写处理。 如果多个线程同时访问某个公有变量,若大部分对其写操作...
  • u014692005
  • u014692005
  • 2016年01月28日 09:55
  • 400

ACE框架整合记录1基础框架【完结】

2016-4-11 21:31更新内容 1,新增谷歌支持 2,处理Tab标签内部padding-16*12引起的下边距太大和双滚动条的问题的问题      修复前后对比      初次加载是正...
  • qq873113580
  • qq873113580
  • 2016年05月16日 15:15
  • 2595

Reactor Proactor 两个IO多路复用的方法

今天看了一篇文章,感觉不错,就决定翻译一下。原文:http://www.artima.com/articles/io_design_patterns2.html 译文: 比较两个高性能的 I/O 设计...
  • zj510
  • zj510
  • 2015年03月24日 12:10
  • 1013

epoll实现Reactor模式

转自:http://blog.csdn.net/analogous_love/article/details/53319815 最近一直在看游双的《高性能Linux服务器编程》一书,下载链接...
  • rankun1
  • rankun1
  • 2017年04月09日 22:41
  • 1033

ACE框架理解(一)

一、框架的理解 1. 框架与类库之间的比较 类强调数据及对数据操作的方法的内聚性,所以其支持比函数库更加有效的小规模的复用。且其并未捕捉软件中的规范控制流、协作和可变性,因而虽广泛应用但有效范围...
  • chinaclock
  • chinaclock
  • 2015年10月15日 20:29
  • 4297

ACE框架解读 - 源码篇

最近学习ACE框架的源码,先考虑选取最新版本ACE6.0来阅读,但是发现代码量有30多万行,规模太大了花的时间会比较多,所以考虑选取旧一些的版本,最后选取ACE4.5版本来阅读,代码量13万行比较适中...
  • gary531
  • gary531
  • 2013年09月07日 10:07
  • 3431

ACE框架简介以及一个基于ACE的C/S服务程序实例

前段时间参与一个C/S结构的系统的开发,使用C++,其中server端的系统要实现Linux和windows系统的跨平台。因为系统的结构和业务逻辑都不太复杂,所以开始就决定不使用类似ACE或Boost...
  • suxinpingtao51
  • suxinpingtao51
  • 2013年09月18日 11:00
  • 9299

ACE,一个C++的框架

ACE自适配通信环境(ADAPTIVE Communication Environment)是可以自由使用、开放源码的面向对象(OO)框架(Framework),在其中实现了许多用于并发通信软件的核心...
  • fuyuehua22
  • fuyuehua22
  • 2014年01月05日 17:57
  • 4224

ACE的框架及其核心

ACE设计框架和基础模块的关联 *一、案例描述 视频电警开发,是基于ACE框架上的一次重复开发,本文档拟对ACE框架做一个梳理,以期对他人进行基于ace的开发有所帮助。 *二、系统安装 ...
  • chinaclock
  • chinaclock
  • 2015年09月22日 14:27
  • 1745
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:ACE中的Reactor框架简介
举报原因:
原因补充:

(最多只允许输入30个字)