封装epoll的异步API

Time: 一月 9, 2011
Category: Programming practices

epoll的设计坚持Unix哲学KISS原则,keep it simple, stupid

但是KISS并不等于实用。epoll提供三个简单的函数供应用程序进行异步事件处 理,epoll_create(),epoll_ctl(),epoll_wait()。这几个函数并不友好,尤其面对复杂的业务逻辑时,缺乏清晰的思路, 需要进一步的封装。

通常开发人员需要什么:

  1. 异步处理的对象,文件描述符
  2. 需要监听的事件,可读或可写(EPOLLIN|EPOLLOUT)
  3. 事件产生时的处理函数,epoll并不提供,机制与策略分离

所以我对 epoll 提供的接口进行简单易用的封装,以适合更一般化的场景需求。

数据结构

C 代码
  1. typedef void eProc(struct eloop *el, int fd, void *argv, int mask);
  2. /* File event structure */
  3. typedef struct efile {
  4.     int mask;
  5.     eProc *rProc;
  6.     eProc *wProc;
  7.     void *data;
  8. }  efile_t;
  9. typedef struct eloop {
  10.     int efd;
  11.     int stop;
  12.     efile_t ev[AE_SETSIZE];
  13.     efire_t rd[AE_SETSIZE];
  14. } EL;

efile_t 作为基本的异步io对象,保存事件发生时调用的处理函数以及传参的数据。eloop 为最主要的数据结构,efd 为 epoll_create() 返回的 epoll 专用描述符号,负责多个epoll_event。ev[AE_SETSIZE] 保存正在监听的所有事件。如果 epoll_t 是监控机,则 efd为执行者,events 为被监控对象。每次 epoll_wait() 返回的结果保存在 rd[AE_SETSIZE] 里。

编程接口

C 代码
  1. EL *el_open(void);
  2. int el_close(EL *el);
  3. int el_stop(EL *el);
  4. int el_start(EL *el, int flags);
  5. int el_addFileEvent(EL *el, int fd, int mask, eProc *pro, void *data);
  6. int el_delFileEvent(EL *el, int fd, int mask);

这套 API 的使用很方便,el_start() 启动论询,el_stop()暂停论询,el_addFileEvent() 往 EL 中添加一个事件,支持注册回调函数,el_delFileEvent() 删除一个事件,代码没有经过测试,谨慎使用。

>>具体设计看源代码

2 comments to “封装epoll的异步API”

  1. Bluefoxah说道:

    请问,这个具体的实现有代码吗?nn1

Leave a Comment