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中所有句柄不一定都激活了,那么这么做岂不错了?
ACE文档里面有说明,ACE对select模式有了改进,不使用传统的操作模式,这样提高了性能。 winston 发表于 2014-3-31 08:45
ACE文档里面有说明,ACE对select模式有了改进,不使用传统的操作模式,这样提高了性能。 ...
传统的方式是:应用程序必须收集每一个句柄集,以找到活动句柄。
但是查看operator()的源码,返回的句柄不一定是活动的。
本帖最后由 yunh 于 2014-4-1 11:17 编辑
Windows 上的实现与 Unix 有所不同,Windows 的 select 每次返回的 Set 中只包含已激活的句柄,不用再遍历句柄集一一判断
是这样的,但是在 Unix 上,这是通过一个掩码位来取得的,也就是说如果一个句柄对应的激发了,它会被置位为1,否则为0,但如果挨个遍历这个集合来确定哪个句柄被置位就会比较没有效率,所以 ACE 引入了一种快速检索的算法;但是对于 Windows 平台来说就没有必要了,它一个句柄就是一个4字节整数,直接取得就可以了。
页:
[1]