libevent源码深度剖析十

来源:互联网 发布:centos安装tomcat 编辑:程序博客网 时间:2024/05/16 07:37

libevent源码深度剖析十

——支持I/O多路复用技术
张亮

      Libevent的核心是事件驱动、同步非阻塞,为了达到这一目标,必须采用系统提供的I/O多路复用技术,而这些在Windows、Linux、Unix等不同平台上却各有不同,如何能提供优雅而统一的支持方式,是首要关键的问题,这其实不难,本节就来分析一下。

1 统一的关键

      Libevent支持多种I/O多路复用技术的关键就在于结构体eventop,这个结构体前面也曾提到过,它的成员是一系列的函数指针, 定义在event-internal.h文件中:

[cpp] view plain copy
  1. struct eventop {  
  2.     const char *name;  
  3.     void *(*init)(struct event_base *); // 初始化  
  4.     int (*add)(void *, struct event *); // 注册事件  
  5.     int (*del)(void *, struct event *); // 删除事件  
  6.     int (*dispatch)(struct event_base *, void *, struct timeval *); // 事件分发  
  7.     void (*dealloc)(struct event_base *, void *); // 注销,释放资源  
  8.     /* set if we need to reinitialize the event base */  
  9.     int need_reinit;  
  10. };  

      在libevent中,每种I/O demultiplex机制的实现都必须提供这五个函数接口,来完成自身的初始化、销毁释放;对事件的注册、注销和分发。
比如对于epoll,libevent实现了5个对应的接口函数,并在初始化时并将eventop的5个函数指针指向这5个函数,那么程序就可以使用epoll作为I/O demultiplex机制了。

2 设置I/O demultiplex机制

      Libevent把所有支持的I/O demultiplex机制存储在一个全局静态数组eventops中,并在初始化时选择使用何种机制,数组内容根据优先级顺序声明如下:

[cpp] view plain copy
  1. /* In order of preference */  
  2. static const struct eventop *eventops[] = {  
  3. #ifdef HAVE_EVENT_PORTS  
  4.     &evportops,  
  5. #endif  
  6. #ifdef HAVE_WORKING_KQUEUE  
  7.     &kqops,  
  8. #endif  
  9. #ifdef HAVE_EPOLL  
  10.     &epollops,  
  11. #endif  
  12. #ifdef HAVE_DEVPOLL  
  13.     &devpollops,  
  14. #endif  
  15. #ifdef HAVE_POLL  
  16.     &pollops,  
  17. #endif  
  18. #ifdef HAVE_SELECT  
  19.     &selectops,  
  20. #endif  
  21. #ifdef WIN32  
  22.     &win32ops,  
  23. #endif  
  24.     NULL  
  25. };   

     然后libevent根据系统配置和编译选项决定使用哪一种I/O demultiplex机制,这段代码在函数event_base_new()中:
[cpp] view plain copy
  1. base->evbase = NULL;  
  2.     for (i = 0; eventops[i] && !base->evbase; i++) {  
  3.         base->evsel = eventops[i];  
  4.         base->evbase = base->evsel->init(base);  
  5.     }   

    可以看出,libevent在编译阶段选择系统的I/O demultiplex机制,而不支持在运行阶段根据配置再次选择。
    以Linux下面的epoll为例,实现在源文件epoll.c中,eventops对象epollops定义如下:
[cpp] view plain copy
  1. const struct eventop epollops = {  
  2.     "epoll",  
  3.     epoll_init,  
  4.     epoll_add,  
  5.     epoll_del,  
  6.     epoll_dispatch,  
  7.     epoll_dealloc,  
  8.     1 /* need reinit */  
  9. };  

变量epollops中的函数指针具体声明如下,注意到其返回值和参数都和eventop中的定义严格一致,这是函数指针的语法限制。
[cpp] view plain copy
  1. static void *epoll_init    (struct event_base *);  
  2. static int epoll_add    (void *, struct event *);  
  3. static int epoll_del    (void *, struct event *);  
  4. static int epoll_dispatch(struct event_base *, void *, struct timeval *);  
  5. static void epoll_dealloc    (struct event_base *, void *);  

      那么如果选择的是epoll,那么调用结构体eventop的init和dispatch函数指针时,实际调用的函数就是epoll的初始化函数epoll_init()和事件分发函数epoll_dispatch()了;
     关于epoll的具体用法这里就不多说了,可以参见介绍epoll的文章(本人的哈哈):
http://blog.csdn.net/sparkliang/archive/2009/11/05/4770655.aspx


     C++语言提供了虚函数来实现多态,在C语言中,这是通过函数指针实现的。对于各类函数指针的详细说明可以参见文章:
http://blog.csdn.net/sparkliang/archive/2009/06/09/4254115.aspx 
同样的,上面epollops以及epoll的各种函数都直接定义在了epoll.c源文件中,对外都是不可见的。对于libevent的使用者而言,完全不会知道它们的存在,对epoll的使用也是通过eventop来完成的,达到了信息隐藏的目的。

3 小节

    支持多种I/O demultiplex机制的方法其实挺简单的,借助于函数指针就OK了。通过对源代码的分析也可以看出,Libevent是在编译阶段选择系统的I/O demultiplex机制的,而不支持在运行阶段根据配置再次选择。

0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 新买的蓝牙耳机开不了机怎么办 蓝牙耳机长时间不用开不了机怎么办 瑞和宝pos机无法连接蓝牙怎么办 手机做话筒连蓝牙音箱不同步怎么办 荣耀畅玩7x触屏不灵怎么办 华为6x屏幕点没反应怎么办 苹果耳机按一下就挂断电话怎么办 华为畅享7忘记账号密码怎么办 华为荣耀8手机外放声音小怎么办 安卓手机耳机减音量不能用怎么办 苹果手机微信语音是耳机模式怎么办 平果手机没声音出现耳机模式怎么办 苹果6s进水了一直耳机模式怎么办 华为手机没声音显示耳机模式怎么办 华为手机没声音出现耳机模式怎么办 安卓手机全民k歌耳返延迟怎么办 华为手机双清后手机开不了机怎么办 荣耀9上面有个耳机标志怎么办 华为p9耳机有一个没有声音怎么办 小米5c手机gps信号弱怎么办 华为8手机时常听常音乐声怎么办 手机用久了变慢了怎么办 免税店买的皮带太短了怎么办 小米手机自拍照片是反的怎么办 华为p20旅行助手被删了怎么办 假如手机点击一个链接是病毒怎么办 华为手机自带铃声没了怎么办 华为手机升级后铃声没了怎么办 华为平板电脑激活锁忘记了怎么办 华为手机不小心删了系统应用怎么办 华为畅想6s开机键坏了怎么办 浏览网页是进入有病毒的网页怎么办 华为荣耀7清理加速那么慢怎么办 华为手机自带天气卸载了怎么办 手机被病毒感染了开不了机了怎么办 小米手机系统桌面已停止运行怎么办 三星手机应用锁密码忘了怎么办 手机管家应用加密密码忘记了怎么办 下载东西呗安全管家制止了该怎么办 手机百度时不小心中毒扣话费怎么办 手机扫二维码中了木马病毒要怎么办