9 ACE_Dev_Poll_Reactor的处理优先级严重偏向定时器
不使用POLL和EPOLL【注】的人,估计不太知道这个ACE_Dev_Poll_Reactor,但实际上。特别是Linux下的EPOLL(一个IO多路服用模型),这是Linux大规模接入的重要法宝,从目前的表现来看,其他平台上还没有可以超越EPOLL的东西,Windows下的异步IO的性能也还远远逊于EPOLL。
如果要使用EPOLL而不是POLL,要使用宏ACE_HAS_EVENT_POLL编译ACE,大体位置在重复编译的卫哨后面,#include /**/ "ace/pre.h"前面。保证起到作用。
#ifndef ACE_CONFIG_LINUX_H
#define ACE_CONFIG_LINUX_H
// ACE_HAS_EVENT_POLL宏用于定义使用EPOLL模块,同时注意不同LINUX平台下编译可能有少量
//不同。我曾经使用过的一个内核2.4的Slackware平台,要在编译ACE的时候加入 –lepoll,可能是由于
#define ACE_HAS_EVENT_POLL
#include /**/ "ace/pre.h"
但也许是由于这个东西过新还是由于设计者是一个定于时间要求很敏感的人。的设计明显的是定时器优先。但是了解EPOLL和POLL的人都知道,UNIX和Linux设计这两个咚咚的目的就是解决大规模IO复用。不是为了保证定时器优先,所以我对这个设计很是不解,郁闷。其大体思路为,
1.) 先检查定时器超时的队列,计算最小的超时时间,用于IO等待。
2.) 触发IO事件
3.) 处理超时的Handler,如果有超时的事件,返回(1)。这点我看得最郁闷。
4.) 再分发处理IO事件
可以看到在处理超时句柄的时候,ACE_Dev_Poll_Reactor发现有超时的事件会返回到检查超时队列。所以如果在Reactor同时有定时处理,IO的优先级会很低。
其实这个的设计者也知道这个问题。他在代码中间做了如下的记录。
int
ACE_Dev_Poll_Reactor::dispatch (Token_Guard &guard)
{
……
// Handle timers early since they may have higher latency
// constraints than I/O handlers. Ideally,the order of
// dispatching should be a strategy...
if ((result = this->dispatch_timer_handler (guard)) != 0)
return result;
由于EPOLL的特性,使用它大部分都是为了处理大规模的IO请求,定时器其实只有少量的需求,不是我们需求的重点。
这个问题到最近的
我曾经反馈过这个问题。但是得到没有明确的解答。解决这个问题的方法其实也很简单,自己重载这个类,然后自己实现相应的函数。触发IO事件后立即分发IO事件,而且加入了一个IO的优先级别。在多次IO处理的循环后在进入时间事件处理。保证时间处理的粒度在1s以内基本就可以了。