编辑: 无理的喜欢 2017-12-17
第6章 反应堆(Reactor):用于事件多路分离和分派的体系结构模式 反应堆模式一直在发展之中,以为高效的事件多路分离和分派提供可扩展的面向对象构架.

目前用于事件多路分离的OS抽象既复杂又难以使用,因而也容易出错.反应堆本质上提供一组更高级的编程抽象,简化了事件驱动的分布式应用的设计和实现.除此而外,反应堆还将若干不同种类的事件的多路分离集成到易于使用的API中.特别地,反应堆对基于定时器的事件、信号事件、基于I/O端口监控的事件和用户定义的通知进行统一地处理. 在本章里,我们描述怎样将反应堆用于对所有这些不同的事件类型进行多路分离. 6.1 反应堆组件 图6-1 反应堆中的内部组件和外部组件的协作 如图6-1所示,ACE中的反应堆与若干内部和外部组件协同工作.其基本概念是反应堆构架检测事件的发生(通过在OS事件多路分离接口上进行侦听),并发出对预登记事件处理器(event handler)对象中的方法的 回调 (callback).该方法由应用开发者实现,其中含有应用处理此事件的特定代码. 于是用户(也就是,应用开发者)必须: 创建事件处理器,以处理他所感兴趣的某事件. 在反应堆上登记,通知说他有兴趣处理某事件,同时传递他想要用以处理此事件的事件处理器的指针给反应堆. 随后反应堆构架将自动地: 在内部维护一些表,将不同的事件类型与事件处理器对象关联起来. 在用户已登记的某个事件发生时,反应堆发出对处理器中相应方法的回调. 6.2 事件处理器 反应堆模式在ACE中被实现为ACE_Reactor类,它提供反应堆构架的功能接口. 如上面所提到的,反应堆将事件处理器对象作为服务提供者使用.一旦反应堆成功地多路分离和分派了某事件,事件处理器对象就对它进行处理.因此,反应堆会在内部记住当特定类型的事件发生时,应该回调哪一个事件处理器对象.当应用在反应堆上登记它的处理器对象,以处理特定类型的事件时,反应堆会创建这种事件和相应的事件处理器的关联. 因为反应堆需要记录哪一个事件处理器将被回调,它需要知道所有事件处理器对象的类型.这是通过替换模式(Substitution Pattern)的帮助来实现的(或者换句话说,通过 是……类型 (is a type of)变种继承).该构架提供名为ACE_Event_Handler的抽象接口类,所有应用特有的事件处理器都必须由此派生(这使得应用特有的处理器都具有相同的类型,即ACE_Event_Handler,所以它们可以相互替换).要了解此概念的更多细节,请阅读替换模式的参考资料[V]. 如果你留意上面的组件图,其中的事件处理器的椭圆形包括灰色的Event_Handler部分,对应于ACE_Event_Handler;

以及白色的部分,它对应于应用特有的部分. 图6-2对其进行说明: 图6-2 ACE_Event_Handler类图 ACE_Event_Handler类拥有若干不同的 handle (处理)方法,每个处理方法被用于处理不同种类的事件.当应用程序员对特定事件感兴趣时,他就对ACE_Event_Handler类进行子类化,并实现他感兴趣的处理方法.如上面所提到的,随后他就在反应堆上为特定事件 登记 他的事件处理器类.于是反应堆就会保证在此事件发生时,自动回调在适当的事件处理器对象中的适当的 handle 方法. 使用ACE_Reactor基本上有三个步骤: 创建ACE_Event_Handler的子类,并在其中实现适当的 handle_ 方法,以处理你想要此事件处理器为之服务的事件类型.(参看表6-1来确定你需要实现哪一个 handle_ 方法.注意你可以使用同一个事件处理器对象处理多种类型的事件,因而可以重载多于一个的 handle_ 方法.) 通过调用反应堆对象的register_handler(),将你的事件处理器登记到反应堆. 在事件发生时,反应堆将自动回调相应的事件处理器对象的适当的 handle_ 方法. 下面的简单例子可以帮助我们更好地理解这些步骤: 例6-1 #include #include ace/Reactor.h #include ace/Event_Handler.h //Create our subclass to handle the signal events //that we wish to handle. Since we know that this particular //event handler is going to be using signals we only overload the //handle_signal method. class MyEventHandler: public ACE_Event_Handler { int handle_signal(int signum, siginfo_t*,ucontext_t*) { switch(signum) { case SIGWINCH: ACE_DEBUG((LM_DEBUG, You pressed SIGWINCH \n ));

下载(注:源文件不在本站服务器,都将跳转到源网站下载)
备用下载
发帖评论
相关话题
发布一个新话题