|
一般常见的Epoll的处理是如下的办法,
for ( ; ; )
{
nfds = epoll_wait(kdpfd, events, maxevents, -1);
for(n = 0; n < nfds; ++n)
{
//handle socket event
}
}
最近看ACE_Dev_Poll_Reactor的源代码实现,有点类似于TP_Reactor的领导者跟随者的线程池实现机制,
简化的网络事件处理流程应该是这样的:
首先进入handle_event函数会申请token如果成功将成为owner(领导者),然后只有owner可以调用Epoll函数
int const nfds = ::epoll_wait (this->poll_fd_,
&this->event_,
1,
static_cast<int> (timeout));
如果有网络事件需要处理的话,在handler_rep中根据fd找到ACE_Event_Handler指针然后,释放Token,成为跟随者,
其他执行完毕,申请到token的跟随者线程将成为领导者,执行上述步骤。
跟随者线程根据事件类型,调用handle_input,handle_output等函数,执行真正的网络读写操作,接下来的流程略。
这里有两个问题:
1.首先按照上面这个逻辑,假如有100个网络事件到来的话,如果是单线程处理的话,那么一定需要调用100次epoll_wait,才会处理完,
这样的效率肯定不会比假设maxevents设置为20,调用epoll_wait函数5次,每次顺序处理二十个请求来的高,不知道这么理解是否正确。
或许epoll_wait调用的开销相对甚小至可以大致忽略。
2.ACE_Dev_Poll_Reactor是否可以像TP_Reactor一样,使用线程池去运行Reactor事件循环,从代码处理逻辑上看两者在原理上有很大的相似点。
这或许是一个可能的解释,结果像TP_Reactor一样是多个线程可以同时对不同I/O句柄进行读写,想必效率是有提升的。
继而我查了一些ACE的资料以及参考了一些相关文章,但是并没有找到准确的说法,
一些文章上说ACE_Dev_Poll_Reactor用线程池处理的话会有bug,不过也没有具体指出。
查了ACE自带Dev_Poll_Reactor的例子也是单线程运行Reactor事件循环的。
3.最后有这方面相关经验的同志是否可以分享一下ACE_Dev_Poll_Reactor使用的经验。
[ 本帖最后由 modern 于 2009-11-8 17:18 编辑 ] |
|