1. 程式人生 > >C++ Epoll的封裝

C++ Epoll的封裝

Epoller元件的實現主要是對於epoll_create,epoll_ctl,epoll_wait等的封裝,該Epoll可以設定
可選擇採用邊緣觸發還是選擇觸發的模式bEt,預設為邊緣觸發 
可指定該Epoll可以指定監聽的最大套接字數目max_connections

/**
 * @brief epoller操作類,已經預設採用了EPOLLET方式做觸發
 */
class TC_Epoller
{
public:

     /**
      *

@brief 建構函式.
      * 
     * @param bEt 預設是ET模式,當狀態發生變化的時候才獲得通知
      */
     TC_Epoller(bool bEt = true);

     /**
     *

@brief 析夠函式.
      */
     ~TC_Epoller();

     /**
      * @brief 生成 epoll控制代碼.
      * 
     * @param max_connections epoll服務需要支援的最大連線數
      */
     void create(int max_connections);

     /**
      * @brief 新增監聽控制代碼.
      * 
     * @param fd    控制代碼
     * @param data  輔助的資料, 可以後續在epoll_event中獲取到
     * @param event 需要監聽的事件EPOLLIN|EPOLLOUT
     *             
      */
     void add(int fd, long long data, __uint32_t event);

     /**
      * @brief 修改控制代碼事件.
      * 
     * @param fd    控制代碼
     * @param data  輔助的資料, 可以後續在epoll_event中獲取到
     * @param event 需要監聽的事件EPOLLIN|EPOLLOUT
      */
     void mod(int fd, long long data, __uint32_t event);

     /**
      * @brief 刪除控制代碼事件.
      * 
     * @param fd    控制代碼
     * @param data  輔助的資料, 可以後續在epoll_event中獲取到
     * @param event 需要監聽的事件EPOLLIN|EPOLLOUT
      */
     void del(int fd, long long data, __uint32_t event);

     /**
      * @brief 等待時間.
      * 
      * @param millsecond 毫秒
     * @return int       有事件觸發的控制代碼數
      */
     int wait(int millsecond);

     /**
     * @brief 獲取被觸發的事件.
      *
      * @return struct epoll_event&被觸發的事件
      */
     struct epoll_event& get(int i) { assert( _pevs != 0); return _pevs [i]; }

protected:

     /**
      * @brief 控制 epoll,將EPOLL設為邊緣觸發EPOLLET模式
     * @param fd    控制代碼,在create函式時被賦值
     * @param data  輔助的資料, 可以後續在epoll_event中獲取到
     * @param event 需要監聽的事件
      * @param op    EPOLL_CTL_ADD: 註冊新的 fd到epfd 中;
      *                  EPOLL_CTL_MOD:修改已經註冊的 fd的監聽事件;
      *                  EPOLL_CTL_DEL:從 epfd中刪除一個fd;
      * 
      */
     void ctrl(int fd, long long data, __uint32_t events, int op);

protected:

    /**
     *      epoll
     */
    int _iEpollfd;

     /**
     * 最大連線數
      */
     int   _max_connections;

     /**
     * 事件集
      */
     struct epoll_event *_pevs;

    /**
     * 是否是ET模式
     */
    bool _et;
};


TC_Epoller::TC_Epoller(bool bEt)
{
     _iEpollfd   = -1;
     _pevs       = NULL;
    _et         = bEt;
     _max_connections = 1024;
}

TC_Epoller::~TC_Epoller()
{
     if(_pevs != NULL)
     {
            delete[] _pevs;
            _pevs = NULL;
     }

     if(_iEpollfd > 0)
     {
            close(_iEpollfd);
     }
}

void TC_Epoller::ctrl(int fd, long long data, __uint32_t events, int op)
{
     struct epoll_event ev;
     ev.data.u64 = data;
    if(_et)
    {
        ev.events   = events | EPOLLET ;
    }
    else
    {
        ev.events   = events;
    }

     epoll_ctl(_iEpollfd , op, fd, &ev);
}

void TC_Epoller::create(int max_connections)
{
     _max_connections = max_connections;

     _iEpollfd = epoll_create(_max_connections + 1);

     if(_pevs != NULL)
     {
            delete[] _pevs;
     }

     _pevs = new epoll_event[_max_connections + 1];
}

void TC_Epoller::add(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_ADD);
}

void TC_Epoller::mod(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_MOD);
}

void TC_Epoller::del(int fd, long long data, __uint32_t event)
{
     ctrl(fd, data, event, EPOLL_CTL_DEL);
}

int TC_Epoller::wait(int millsecond)
{
     return epoll_wait(_iEpollfd , _pevs , _max_connections + 1, millsecond);
}

--------------------- 
作者:turkeyzhou 
來源:CSDN 
原文:https://blog.csdn.net/turkeyzhou/article/details/8759527 
版權宣告:本文為博主原創文章,轉載請