sushe2111 发表于 2014-3-31 00:52:19

ACE 反应式服务器对ACE_Handle_Set_Iterator 的疑惑

最近在学习ACE的《C++网络编程 卷一:运用ACE和模式消除复杂性》。目前学习到第七章“ACE的同步事件多路分离包装器外观”对于类ACE_Handle_Set_Iterator有些疑惑,希望各位帮忙解答下。如下:
virtual int handle_data (ACE_SOCK_Stream *) {
    ACE_Handle_Set_Iterator peer_iterator (active_handles_);
    for (ACE_HANDLE handle;
         (handle = peer_iterator ()) != ACE_INVALID_HANDLE;
         ) {
      logging_handler ().peer ().set_handle (handle);
      if (logging_handler ().log_record () == -1) {
      // Handle connection shutdown or comm failure.
      master_handle_set_.clr_bit (handle);
      logging_handler ().close ();
      }
    }
    return 0;
}
在此函数中使用了ACE_Handle_Set_Iterator类,在断定fd_set中的句柄是否激活时,调用了ACE_Handle_Set_Iterator的operator()方法。查看operator()中关于win的具体实现:
ACE_HANDLE
ACE_Handle_Set_Iterator::operator () (void)
{
ACE_TRACE ("ACE_Handle_Set_Iterator::operator");
#if defined (ACE_WIN32)
if (this->handle_index_ < this->handles_.mask_.fd_count)
    // Return the handle and advance the iterator.
    return (ACE_HANDLE) this->handles_.mask_.fd_array;
else
    return ACE_INVALID_HANDLE;

#elif !defined (ACE_HAS_BIG_FD_SET) /* !ACE_WIN32 */
......................................
由上可以看出此函数直接返回handle,并没有进行is_set(),fd_array中所有句柄不一定都激活了,那么这么做岂不错了?

winston 发表于 2014-3-31 08:45:02

ACE文档里面有说明,ACE对select模式有了改进,不使用传统的操作模式,这样提高了性能。

sushe2111 发表于 2014-3-31 13:32:57

winston 发表于 2014-3-31 08:45
ACE文档里面有说明,ACE对select模式有了改进,不使用传统的操作模式,这样提高了性能。 ...


传统的方式是:应用程序必须收集每一个句柄集,以找到活动句柄。

但是查看operator()的源码,返回的句柄不一定是活动的。

yunh 发表于 2014-4-1 11:10:49

本帖最后由 yunh 于 2014-4-1 11:17 编辑

Windows 上的实现与 Unix 有所不同,Windows 的 select 每次返回的 Set 中只包含已激活的句柄,不用再遍历句柄集一一判断

sushe2111 发表于 2014-4-1 12:47:16


yunh 发表于 2014-4-1 14:47:19

是这样的,但是在 Unix 上,这是通过一个掩码位来取得的,也就是说如果一个句柄对应的激发了,它会被置位为1,否则为0,但如果挨个遍历这个集合来确定哪个句柄被置位就会比较没有效率,所以 ACE 引入了一种快速检索的算法;但是对于 Windows 平台来说就没有必要了,它一个句柄就是一个4字节整数,直接取得就可以了。
页: [1]
查看完整版本: ACE 反应式服务器对ACE_Handle_Set_Iterator 的疑惑