ACE_Reactor学习3 ACE_Reactor初始化相关的实现分析

    1. ACE_Reactor构造函数,  定制Reator的底层实现机制

           1. ACE_Reactor (ACE_Reactor_Impl *implementation = 0, bool delete_implementation = false)

           2. 在构造reactor时, 用户可以自己指定底层reactor的具体实现方式(实现方式见ACE_Reactor学习1图2), 通过第一个参数将实现和reactor绑定, 第二个参数是Reactor析构是是否调用delete将implementation 删掉, 前面一节也已有记录

           3. 默认参数情况下, 底层实现将指定为ACE_WFMO_Reactor, ACE_Select_Reactor, ACE_Dev_Poll_Reactor

    2. ACE_Reactor::open函数,

           1. int open (size_t max_number_of_handles, int restart = 0,ACE_Sig_Handler *signal_handler = 0,ACE_Timer_Queue *timer_queue = 0)

           2. 参数的含义比较明确, max_..支持最大的handler数, restart是党select函数被中断后, 是停止Loop返回, 还是重启select, signal_handler是对信号的处理的支持, timer_queue是对时间的处理的支持

           3. open实际上是通过转发到底层的imp的open方法.以select的实现为例子, 实际上这个函数的实现是在ACE_Select_Reactor_T::open中实现, 根据默认参数, 可以得出max_number_of_handles是当前系统中FD_SETSIZE的定义(比如windows下就是定义为1024), restart=0不重新启动select(当select被中断时), sig_hanle和timer_queue默认参数都是null

   open的流程:

       1. 检测是否inited, 及是否已经初始化, 防止多次初始化

       2. 将reator的owner线程设置为自己, 这个很重要~~~这里就有一种假设, 就是如果你在同一个线程中创建select_reactor, 并在这个线程里面去调用event_loop的话, 就不用显示调用owner将reactor和这个线程绑定, 因为这里的open函数表明:"reactor默认的owner是创建它的线程", 如果是在不同的线程中进行reactor的创建和event_loop, 那么在loop前必须用owner方法将线程和reactor绑定, 同一时刻reactor只能属于同一线程[注意, 在TP_Select中是另外一种机制]

       3. 设置restart属性

       4. 如果有可用的sig_handle(对应参数不为null), 那么设置reactor的sig_handler, 否者new一个ace_sig_handler

       5. 如果有可用的timer_handle(同上), 那么设置reactor的timer_handler, 否者new一个ace_timer_heap(时间按堆组成)

       6. 如果有可用的notify_handle(同上), 那么设置reactor的notify_handler, 否者new一个ace_select_reactor_notify, 并打开

       7. 如果上述操作成功, 设置inited=true

   注意: 注意这个imp->open的调用时机, 根据代码中来看, 在select_reactor的两个构造函数中, 都会调用open函数, 也就是说这个open函数是不用手动去调用的, 你手动调用时, open函数会在步骤1中return掉, 但是reactor中还是给出了open这样一个接口, 其实现是调用imp->open, 呵呵, 为什么要这个接口, 它存在的意义是什么? 也许是为了别的实现来说有用, 但是不管怎么这个接口的存在都让人理解reactor增加了难度~~~

     3. 总结:

         1. reacotr的初始化总结[以select为例]

             1. 用户自己定义一个reactor_imp, 在reactor_imp的构造函数中会调用open, 把一切都初始化好[初始化Core]

     2. 将reactor_imp和一个reactor绑定起来, 然后使用reactor的一致的接口来操作reactor_imp[绑定Interface] 

     仔细理解这两句话, 真的觉得这种手法十分的强大, 通过一个安装过程, 将一个Core(功能内核)和一个Interface(接口界面)绑定在一起. 即提供了一个一致的访问界面, 也提供了一个可以拔插替换的核心~~~~不由的对ace的作者充满敬意, 虽然看过设计模式, 虽然了解一些解耦合的方法, 哪有怎样?? 能真正把这些思想和方法在实际的工作实践中运用到自如的人, 真的是太厉害了:)

ps: 注意细节, 用静态ACEs.lib时, 不但要把lib包进来, 而且在工程中要定义ACE_AS_STATIC_LIBS, 否则会发生link error

原文地址:https://www.cnblogs.com/ringofthec/p/ace.html