找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 8914|回复: 16

请教大家关于ACE_Dev_Poll_Reactor的问题

[复制链接]
发表于 2009-11-8 17:12:32 | 显示全部楼层 |阅读模式
一般常见的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 编辑 ]
发表于 2009-11-9 16:22:30 | 显示全部楼层
呵呵,modern也在研究ACE_Dev_Poll_Reactor啊,我现在正好也在搞它,多交流啊
现在比较忙,凭印象大概说下,晚上回去再认真整理下想法

1,ACE_Dev_Poll_Reactor好像不用owner
2,token是reactor的,考虑的是多线程跑reactor时,handler的注册和撤销的同步
3,每次dispatch一个event,是为了多线程,每个线程一次得到一个处理任务。公平性依赖epoll内在机制。
4,多线程类似iocp,是为了用满多cpu的能力,一般可设为 cpu数*2,这是假设有50%的线程会处于wait状态。
5,没有实现et模式
6,实现了oneshot,但是不是我所理想的oneshot,handle_*()后又塞了回去。个人初步想法:lt + noneblock + oneshot == et + oneshot。
发表于 2009-11-9 20:47:53 | 显示全部楼层
Modern你在哪里找到的ACE自带Dev_Poll_Reactor的例子啊?我怎么搜索了半天也没找到。。。
发表于 2009-11-9 20:49:52 | 显示全部楼层
其实epoll和select语义是一样的,那么既然有TP_(Select_)Reactor,就可以有TP_(Epoll_)Reactor,只是把select机制改成epoll就可以了,其他的leader/follower机制不动。
发表于 2009-11-9 20:59:44 | 显示全部楼层
。。。。

[ 本帖最后由 wishel 于 2009-11-11 15:53 编辑 ]
发表于 2009-11-9 21:04:04 | 显示全部楼层
当然可以使用多线程处理啦。
参考一下这个:
http://www.monkey.org/~provos/libevent/
 楼主| 发表于 2009-11-10 13:09:03 | 显示全部楼层
例子参考$ACE_ROOT/tests目录下这个文件Dev_Poll_Reactor_Test.cpp,很简单的一个例子。
 楼主| 发表于 2009-11-10 14:25:04 | 显示全部楼层
回复wishel 2楼
1,我提到的owner是token持有的,与Reactor的owner无关,这里我说的有点歧义。
2,token的用法你说的没错,由于跟我的想描述的主题关系不大,因此我开始没有提及,
另外只有申请到token的才可以成为领导者线程,调用epoll_wait。
确保了同一时刻仅有一个线程可以调用epoll_wait。
3-4,这是我想确认的内容,我亦认为是可以这么用的,不过查了一些帖子,有的说ACE实现的这么用存在bug。
因此向用过的人求证一下,最近比较忙,没有时间做验证。
5,确实没有实现et模式
6,ACE实现了oneshot,这一点我理解的不是很透彻,
我没有看到有使用EPOLLONESHOT禁用Epoll对特定文件描述符的监听。

[ 本帖最后由 modern 于 2009-11-10 14:30 编辑 ]
 楼主| 发表于 2009-11-10 14:28:15 | 显示全部楼层
libevent,有时间参考一下。
发表于 2009-11-10 14:43:52 | 显示全部楼层
。。。。

[ 本帖最后由 wishel 于 2009-11-11 15:53 编辑 ]
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-6-26 20:41 , Processed in 0.030516 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表