通俗理解 ACE_Reactor(转)

ACE_Reactor实现原理,因这边文章把复杂的东西说简单了,很喜欢这种风格,就把它贴上来了,对于新学者其实也很有研究价值

复杂的东西归于简单化思考,其实是很好理解的

来源:宇星软件园     

大半年前买了本ACEC++NPv2,翻了一下感觉满篇理论概念,没有看下去,然后这半年继续实现了些网络程序,前几天再次捧起这本书,先用两天时间囫囵吞枣、一目十行的粗览了一遍,结合自己之前的网络编程经验,感觉到一些共鸣,又再慢慢的进行仔细的阅读,写下自己的阅读体会。

()主要针对ACE_Reactor(反应器、反应堆)

首先,先介绍一下我项目中自己写的一个网络编程库,对比一下,可以很好理解这个ACE_Reactor

我的这个库,代码主要跨Linux/Win32平台,因为没有需要,没在其他平台测试过。这个库没有涉及UI部分,只是用来编写服务器端,或者Linux/Win32的控制台程序。先拿两个类来对比ACE_Reactor

// 回调函数
typedef void (*pfn_sock_event_t)(socket_t* sock, int err, void* param);

// 非阻塞式 socket
class socket_t
{
public:

    ...

    // 创建时,加到 socket_manager_t 管理
    bool create(...)
    {
        ...
        socket_manager_t::add(this, ...);
    }
   
    // attach
时,加到 socket_manager_t 管理
    bool attach(SOCKET s, ...)
    {
        ...
        socket_manager_t::add(this, ...);
    }
   
    //
关闭时从 socket_manager_t 移除
    void close()
    {
        ...
        socket_manager_t::remove(this, ...);
    }
   
    //
设置回调函数
    void set_callback(
            pfn_sock_event_t on_recv = 0,
            pfn_sock_event_t on_send = 0,
            pfn_sock_event_t on_accept = 0,
            pfn_sock_event_t on_close = 0,
            pfn_sock_event_t on_connect = 0,
            pfn_sock_event_t on_except = 0
            );
    ...
   
protected:
    SOCKET m_sock;
   
    pfn_sock_event_t m_on_recv,
    pfn_sock_event_t m_on_send,
    pfn_sock_event_t m_on_accept,
    pfn_sock_event_t m_on_close,
    pfn_sock_event_t m_on_connect,
    pfn_sock_event_t m_on_except
    ...
};

// socket_manager_t
//
拥有一个 sockets 数组或列表,统一一次性进行 select()
class socket_manager_t
{
public:
    ...

    static void add(socket_t* s, ...)
    {
        //
加入到 m_socks
    }
   
    static void remove(socket_t* s, ...)
    {
        //
m_socks 移除
    }
   
    //
一次性对 m_socks 中所有的 socket 进行 select()
    static void poll()
    {
        int sck_cnt = m_socks.size();
        ...
       
        for (i = 0; i < (sck - 1) / FD_SETSIZE + 1; ++i)
        {
            for (j = 0 ;j < FD_SETSIZE; ++j)
            {
                socket_t* sck = m_socks[idx];
               
                if (...) FD_SET(sck->m_sock, fdWrite, ...);
                if (...) FD_SET(sck->m_sock, fdRead, ...);
               
                ...
            }
           
            if (select(...) <= 0) continue;
           
            for (j = 0 ;j < FD_SETSIZE; ++j)
            {
                socket_t* sck = m_socks[idx];
               
                if (FD_ISSET(sck->m_sock, ...), ...)
                     if (sck->m_on_connect) sck->m_on_connect(sck, ...);
               
                if (FD_ISSET(sck->m_sock, ...), ...)
                     if (sck->m_on_close) sck->m_on_close(sck, ...);
               
                if (FD_ISSET(sck->m_sock, ...), ...)
                     if (sck->m_on_accept) sck->m_on_accept(sck, ...);
               
                if (FD_ISSET(sck->m_sock, ...), ...)
                     if (sck->m_on_recv) sck->m_on_recv(sck, ...);
               
                if (FD_ISSET(sck->m_sock, ...), ...)
                     if (sck->m_on_send) sck->m_on_send(sck, ...);
               
                ...
            }
        }
        ...
    }
   
    ...
   
protected:
    ...

    vector<socket_t*> m_socks; 
};

最后,在 main() 中,或者一个独立的线程中,循环执行 socket_manager_t::poll()

void main()
{
   ...
  
   while (!dead_event)
   {
        ...
        socket_manager_t::poll();
        ...
   }
  
   ...
}

简单解说一下:
socket_t::create()
或者 socket_t::attach() 时登记自己到 socket_manager_t 中,由 socket_manager_t::poll()对所有的socket进行select(),触发及分派socket_t::on_recv()/socket_t::on_send()/socket_t::on_accept()等事件。

好,开始涉及ACE_Reactor

功能上,可以等价的认为,上面的 socket_manager_t 就类似是 ACE_Rector,主要作用就是事件触发中心、事件反应器、事件监控器、事件分派器等。

就像上面的 socket 一样,各种 ACE_Event_Handler 及其派生物类,都像 socket_t::create()那样,有个向触发中心登记本身的动作,对于 ACE_Event_Handler 来说,是由程序员明显的调用 ACE_Rector register(...),而 ACE_Event_Handler 本身就有 handle_input()/handle_output() 等虚拟函数,作为回调调用,就像上面的 socket_t::on_recv/socket_t::on_send... 一样。加入到 ACE_Rector 中的各种 ACE_Event_Handler,由 ACE_Rector 调用其他的事件查询/监听方式进行统一监控(比如 socket select()Win32 特有的 WSAEventSelect() ),当有事件在 ACE_Event_Handler 上发生时,调用它的 handle_input()/handle_output()等虚拟函数。

ACE_Event_Handler 进行 ACE_Rector::register() 时,指定 READ_MASK/WRITE_MASK 等自己感兴趣的事件,handle_input()等回调被调用时返回适当的值,以指示 ACE_Rector 取消或继续监控自己。

至于 ACE_Event_Handler 还有个 handle_except() 的虚拟回调函数,跟 socket_t::on_except() 差不多。

ACE_Event_Handler 还有个 handle_timeout() 的虚拟回调,讲解一下。在我的程序中,曾经做过一个


//
回调函数
typedef void (*pfn_timer_event_t)(timer_t* tm, void* param);

class timer_t 
{
   ...
  
   timer_t(pfn_timer_event_t pfn, void* param, uint32 timeout_usecs)
   {
     m_start_tick = util_t::sys_tick();
        timer_manager_t::add(this);
        ...
   }
  
   bool is_timeout(uint32 cur_tick)
   {
        return (cur_tick - m_start_tick >= m_timeout_usecs);
   }
  
   void process()
   {
     if (m_pfn) m_pfn(this, m_param);
   }
 
 protected; 
   pfn_timer_event_t m_pfn;
   void* m_param;
   uint32 m_start_tick;
   uint32 m_timeout_usecs;
};

class timer_manager_t
{
    ...
   
    void add(timer_t* tm)
    {
        //
加入到 m_timers
        ...
    }
   
    void poll()
    {
        uint32 cur_tick = util_t::sys_tick();
       
        for (int i = 0; i < m_timers.size(); ++i)
        {
            if (m_timers[i]->is_timeout(cur_tick))
            {
                //
超时,触发 timer_t 的事件
                m_timers[i]->process();
                ...
            }
            ...
        }
    }
   
   
    vector<timer_t> m_timers;
};

在上面的那个 main,或者一个线程中,比如

void main()
{
   ...
  
   while (!dead_event)
   {
        ...
        socket_manager_t::poll();
        timer_manager_t::poll();
        ...
   }
  
   ...
}

而现在,ACE_Reactor 只不过把这个 timer_manager_t 的功能一起集成进去而已。


最后声明一下,我还没具体看 ACE 的源代码,只是暂时从 <<ACEC++NPv2>> 的讲解上,字面上根据自己的经历大概理解一下 ACE_Reactor,如果有什么错误,后期再改正。本文不打算成为什么学术指南,只作为个人经验参考。

后面的 ACE_Server_Config/ACE_Module/ACE_Task 等等,我粗览过一遍,而我的一个网络服务器程序,前期只是个login server的模块,后期因为业务需要,增加了多种server接口,以及增加了多服务器支持等,扩充维护的经历使我更能体会ACE这些动态配置、模块合作的设计安排。如果有时间,我会再结合自己的经验教训,继续写下自己的心得体会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值