不使用POLL和EPOLL【注】的人,估計不太知道這個ACE_Dev_Poll_Reactor,但實際上。特別是Linux下的EPOLL(一個IO多路服用模型),這是Linux大規(guī)模接入的重要法寶,從目前的表現(xiàn)來看,其他平臺上還沒有可以超越EPOLL的東西,Windows下的異步IO的性能也還遠遠遜于EPOLL。
如果要使用EPOLL而不是POLL,要使用宏ACE_HAS_EVENT_POLL編譯ACE,大體位置在重復編譯的衛(wèi)哨后面,#include /**/ "ace/pre.h"前面。保證起到作用。
#ifndef ACE_CONFIG_LINUX_H
#define ACE_CONFIG_LINUX_H
// ACE_HAS_EVENT_POLL宏用于定義使用EPOLL模塊,同時注意不同LINUX平臺下編譯可能有少量
//不同。我曾經(jīng)使用過的一個內(nèi)核2.4的Slackware平臺,要在編譯ACE的時候加入 –lepoll,可能是由于
//其是打補丁增加的功能
#define ACE_HAS_EVENT_POLL
#include /**/ "ace/pre.h"
但也許是由于這個東西過新還是由于設(shè)計者是一個定于時間要求很敏感的人。的設(shè)計明顯的是定時器優(yōu)先。但是了解EPOLL和POLL的人都知道,UNIX和Linux設(shè)計這兩個咚咚的目的就是解決大規(guī)模IO復用。不是為了保證定時器優(yōu)先,所以我對這個設(shè)計很是不解,郁悶。其大體思路為,
1.) 先檢查定時器超時的隊列,計算最小的超時時間,用于IO等待。
2.) 觸發(fā)IO事件
3.) 處理超時的Handler,如果有超時的事件,返回(1)。這點我看得最郁悶。
4.) 再分發(fā)處理IO事件
可以看到在處理超時句柄的時候,ACE_Dev_Poll_Reactor發(fā)現(xiàn)有超時的事件會返回到檢查超時隊列。所以如果在Reactor同時有定時處理,IO的優(yōu)先級會很低。
其實這個的設(shè)計者也知道這個問題。他在代碼中間做了如下的記錄。
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的特性,使用它大部分都是為了處理大規(guī)模的IO請求,定時器其實只有少量的需求,不是我們需求的重點。
這個問題到最近的5.6.1版本沒有得到解決。
曾經(jīng)反饋過這個問題。但是得到?jīng)]有明確的解答。解決這個問題的方法其實也很簡單,自己重載這個類,然后自己實現(xiàn)相應(yīng)的函數(shù)。觸發(fā)IO事件后立即分發(fā)IO事件,而且加入了一個IO的優(yōu)先級別。在多次IO處理的循環(huán)后在進入時間事件處理。保證時間處理的粒度在1s以內(nèi)基本就可以了。
如果要使用EPOLL而不是POLL,要使用宏ACE_HAS_EVENT_POLL編譯ACE,大體位置在重復編譯的衛(wèi)哨后面,#include /**/ "ace/pre.h"前面。保證起到作用。
#ifndef ACE_CONFIG_LINUX_H
#define ACE_CONFIG_LINUX_H
// ACE_HAS_EVENT_POLL宏用于定義使用EPOLL模塊,同時注意不同LINUX平臺下編譯可能有少量
//不同。我曾經(jīng)使用過的一個內(nèi)核2.4的Slackware平臺,要在編譯ACE的時候加入 –lepoll,可能是由于
//其是打補丁增加的功能
#define ACE_HAS_EVENT_POLL
#include /**/ "ace/pre.h"
但也許是由于這個東西過新還是由于設(shè)計者是一個定于時間要求很敏感的人。的設(shè)計明顯的是定時器優(yōu)先。但是了解EPOLL和POLL的人都知道,UNIX和Linux設(shè)計這兩個咚咚的目的就是解決大規(guī)模IO復用。不是為了保證定時器優(yōu)先,所以我對這個設(shè)計很是不解,郁悶。其大體思路為,
1.) 先檢查定時器超時的隊列,計算最小的超時時間,用于IO等待。
2.) 觸發(fā)IO事件
3.) 處理超時的Handler,如果有超時的事件,返回(1)。這點我看得最郁悶。
4.) 再分發(fā)處理IO事件
可以看到在處理超時句柄的時候,ACE_Dev_Poll_Reactor發(fā)現(xiàn)有超時的事件會返回到檢查超時隊列。所以如果在Reactor同時有定時處理,IO的優(yōu)先級會很低。
其實這個的設(shè)計者也知道這個問題。他在代碼中間做了如下的記錄。
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的特性,使用它大部分都是為了處理大規(guī)模的IO請求,定時器其實只有少量的需求,不是我們需求的重點。
這個問題到最近的5.6.1版本沒有得到解決。
曾經(jīng)反饋過這個問題。但是得到?jīng)]有明確的解答。解決這個問題的方法其實也很簡單,自己重載這個類,然后自己實現(xiàn)相應(yīng)的函數(shù)。觸發(fā)IO事件后立即分發(fā)IO事件,而且加入了一個IO的優(yōu)先級別。在多次IO處理的循環(huán)后在進入時間事件處理。保證時間處理的粒度在1s以內(nèi)基本就可以了。