ACE_Select_Reactor的@H_502_3@Notify功能实现浅析@H_502_3@
作者@H_502_3@ : ydogg @H_502_3@ 如需转载@H_502_3@ ,@H_502_3@ 请注明@H_502_3@@H_502_3@ 但是,为了解决某些特别的原因,如大量的通知存储、规避悬空处理器指针等,@H_502_3@ ACE@H_502_3@ 也提供了一种有别于@H_502_3@ Pipe@H_502_3@ 的解决方案,其采用消息排队的方式工作。当采取这种方式时,需定义@H_502_3@ ACE_HAS_REACTOR_NOTIFICATION_QUEUE@H_502_3@ 宏并重生成@H_502_3@ ACE@H_502_3@ 。@H_502_3@
2. @H_502_3@@H_502_3@@H_502_3@
Notify@H_502_3@的@H_502_3@能力、@H_502_3@风险@H_502_3@和风险@H_502_3@规@H_502_3@避@H_502_3@
@H_502_3@
Notify@H_502_3@
机制最重要的能力是:
1. @H_502_3@@H_502_3@@H_502_3@
让反应器拥有了处理无限处理器的能力
2. @H_502_3@@H_502_3@@H_502_3@
其次是提供了必要时解除反应器事件检查阻塞的能力。@H_502_3@
Reactor@H_502_3@的@H_502_3@notify()@H_502_3@让用户直接提供给@H_502_3@Reactor@H_502_3@待通知反应器的指针,而这些处理器无需注册到反应器上,从而提供了无限的扩展能力。但是,在使用@H_502_3@ACE_Pipe@H_502_3@的实现中,如果使用不当,可能会造成严重的后果。
潜在的风险:
1. @H_502_3@@H_502_3@@H_502_3@
处理器被销毁后,排队等候的对应通知才被分派
2. @H_502_3@@H_502_3@@H_502_3@
ACE_Pipe@H_502_3@的数据缓冲是有限的,大量通知到来可能会造成阻塞甚至死锁@H_502_3@
不过,在采用队列的@H_502_3@Notify实现@H_502_3@中,@H_502_3@ACE@H_502_3@
给提供了问题的解决方法。
1. @H_502_3@@H_502_3@@H_502_3@
采用队列方式可无限扩展@H_502_3@Notify@H_502_3@
的数量
2. @H_502_3@@H_502_3@@H_502_3@
采用队列方式为通知的查询提供的方便,因此@H_502_3@ACE_Reactor@H_502_3@提供@H_502_3@puerge_pending_notifications()@H_502_3@方法来移除指定的通知,当处理器销毁时,可以使用该方法移除当前队列中所有和自己相关的通知,避免了使用悬空指针。
在采用@H_502_3@ACE_Pipe@H_502_3@方式中,@H_502_3@puerge_pending_notifications()@H_502_3@被实现为空方法。@H_502_3@
@H_502_3@
@H_502_3@
@H_502_3@
@H_502_3@@H_502_3@
7. @H_502_3@@H_502_3@@H_502_3@实现分析
其中@H_502_3@ACE_DISABLE_NOTIFY_PIPE_DEFAULT@H_502_3@的@H_502_3@值为@H_502_3@0,@H_502_3@表示默@H_502_3@认@H_502_3@要使用@H_502_3@Notify@H_502_3@功能。@H_502_3@
这@H_502_3@个@H_502_3@值@H_502_3@会@H_502_3@传递给@H_502_3@ACE_Select_Reactor_Notify@H_502_3@的构造函数。@H_502_3@在@H_502_3@open()@H_502_3@的@H_502_3@实现@H_502_3@中:@H_502_3@
如果没有使用外部的@H_502_3@notify@H_502_3@时@H_502_3@,@H_502_3@ACE_Select_Reactor_T@H_502_3@将会@H_502_3@让@H_502_3@notify_handler@H_502_3@指向一个@H_502_3@new@H_502_3@出来的@H_502_3@ACE_Select_Reactor_Notify@H_502_3@类@H_502_3@型的@H_502_3@对@H_502_3@象,并@H_502_3@调@H_502_3@用它的@H_502_3@open()@H_502_3@方法@H_502_3@进@H_502_3@行初始化。@H_502_3@
ACE_Select_Reactor_Notify@H_502_3@的@H_502_3@open()@H_502_3@实现@H_502_3@如下(@H_502_3@删@H_502_3@除@H_502_3@了非关@H_502_3@键@H_502_3@代@H_502_3@码@H_502_3@):@H_502_3@
{
@H_502_3@ select_reactor_@H_502_3@
dynamic_cast@H_502_3@ <@H_502_3@ ACE_Select_Reactor_Impl@H_502_3@ *>@H_502_3@ (r);
@H_502_3@ (select_reactor_@H_502_3@ )
{
errno@H_502_3@ EINVAL;
@H_502_3@ return@H_502_3@ ;
}
@H_502_3@ notification_pipe_.open()@H_502_3@ )
@H_502_3@ ;
@H_502_3@ (ACE::set_flags(@H_502_3@ notification_pipe_.read_handle(),
ACE_NONBLOCK)@H_502_3@
@H_502_3@ register_handler
(@H_502_3@ 502_3@
{
@H_502_3@ ;
}@H_502_3@
注意,@H_502_3@这@H_502_3@里的@H_502_3@disable_notify_pipe@H_502_3@就是@H_502_3@ACE_Select_Reactor_T@H_502_3@的@H_502_3@open()@H_502_3@方法中@H_502_3@传递@H_502_3@的参数,通@H_502_3@过@H_502_3@它,可以@H_502_3@设@H_502_3@置不使用@H_502_3@notify@H_502_3@功能。
可以看出,@H_502_3@ACE_Select_Reactor_Notify@H_502_3@的@H_502_3@open()@H_502_3@的主要功能是初始化自己的@H_502_3@ACE_Pipe@H_502_3@类@H_502_3@型成@H_502_3@员对@H_502_3@象@H_502_3@notification_pipe_@H_502_3@,并把它注册到@H_502_3@Reactor@H_502_3@中,@H_502_3@监测@H_502_3@read@H_502_3@事件。@H_502_3@
ACE_Pipe@H_502_3@的@H_502_3@open()@H_502_3@实现@H_502_3@如下(@H_502_3@Win32@H_502_3@平台并@H_502_3@删@H_502_3@除了非关@H_502_3@键@H_502_3@代@H_502_3@码@H_502_3@):@H_502_3@
ACE_SOCK_Acceptoracceptor;
ACE_SOCK_Connectorconnector;
ACE_SOCK_Streamreader;
ACE_SOCK_Streamwriter;
@H_502_3@ int@H_502_3@ result@H_502_3@ ;
#@H_502_3@ defined(ACE_WIN32)
ACE_INET_Addrlocal_any(static_cast@H_502_3@ u_short@H_502_3@ >@H_502_3@ #endif@H_502_3@
@H_502_3@ (acceptor.open(local_any)@H_502_3@ ||@H_502_3@ acceptor.get_local_addr(my_addr)@H_502_3@
@H_502_3@