ACE中的Reactor框架简介
发布时间:2020-12-15 05:28:05 所属栏目:百科 来源:网络整理
导读:Joise.LI @ 2006-10-16 一、 概要 目前用于事件多路分离的 OS 抽象既复杂又难以使用,因而也容易出错。反应器本质上提供一组更高级的编程抽象,简化了事件驱动的分布式应用的设计和实现。除此而外,反应器还将若干不同种类的事件的多路分离集成到易于使用的
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 ¤t_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
中提供以备继承的事件回调方法:
g)
在处理器上登记或删除某事件:
register_handler
、
remove_handler
、
schedule_timer
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_Reactor
、
Open
:创建并初始化
Reactor
实例
ii.
~ACE_Reactor
、
Close
:清理反应器在初始化时分配的资源
事件处理器的管理:
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
的实现。
四、
后记
Reactor
是
ACE
框架中的基础框架,
Acceptor-Connector
、
Proactor
是依赖于
Reactor
的框架。
五、
作者相关信息:
欢迎大家与我交流,共同学习,共同提高。
joise@126.com,
http://joise.126.com
(编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |