在《libev源码解析——总览》一文中,我们介绍过,libev是一个基于事件的循环库。本文将介绍其和事件及循环之间的关系。(转载请指明出于breaksoftware的csdn博客)

目前ibev支持如下IO事件模型:

  • select模型。对应文件是ev_select.c。
  • poll模型。对应文件是ev_poll.c。
  • epoll模型。对应的文件是ev_epoll.c。
  • port模型。对应文件是ev_port.c。
  • kqueue模型。对应的文件是ev_kqueue.c。
  • iocp模型。即IO完成端口模型(I/O Completion Port)。

这些模型并不是我们这个系列介绍的重点。如果想了解select、poll、epoll模型,可以参阅《朴素、Select、Poll和Epoll网络编程模型实现和分析》系列博文。(下图是select模型的调用逻辑图)

此处我们只要知道它们是libev可选的事件模型即可。至于选择什么模型。要视loop_init的入参flags。

static void noinline ecb_cold
loop_init (EV_P_ unsigned int flags) EV_THROW
{
……
#if EV_USE_IOCPif (!backend && (flags & EVBACKEND_IOCP  )) backend = iocp_init   (EV_A_ flags);
#endif
#if EV_USE_PORTif (!backend && (flags & EVBACKEND_PORT  )) backend = port_init   (EV_A_ flags);
#endif
#if EV_USE_KQUEUEif (!backend && (flags & EVBACKEND_KQUEUE)) backend = kqueue_init (EV_A_ flags);
#endif
#if EV_USE_EPOLLif (!backend && (flags & EVBACKEND_EPOLL )) backend = epoll_init  (EV_A_ flags);
#endif
#if EV_USE_POLLif (!backend && (flags & EVBACKEND_POLL  )) backend = poll_init   (EV_A_ flags);
#endif
#if EV_USE_SELECTif (!backend && (flags & EVBACKEND_SELECT)) backend = select_init (EV_A_ flags);
#endif
……
}

backend是一个用于记录libev使用的是哪种IO模型的标记位。

在每个模型初始化函数中,都需要指定两个模型相关的函数指针。比如epoll模型的初始化函数epoll_init中

int inline_size
epoll_init (EV_P_ int flags)
{
……backend_mintime = 1e-3; /* epoll does sometimes return early, this is just to avoid the worst */backend_modify  = epoll_modify;backend_poll    = epoll_poll;
……
}

而在select模型中则是

int inline_size
select_init (EV_P_ int flags)
{backend_mintime = 1e-6;backend_modify  = select_modify;backend_poll    = select_poll;
……
}

backend_mintime是需要等待事件的超时秒数;backend_modify是轮询中修改事件信息的函数。backend_poll则是等待事件的函数。libev通过上述四个变量,隔离了不同模型选择导致不同函数调用的问题。

但是这儿需要指出的是,libev并没有将这种隔离做彻底。因为在关闭IO模型时,它仍然依靠backend的值,调用了不同函数(ev_loop_destroy中)

#if EV_USE_IOCPif (backend == EVBACKEND_IOCP  ) iocp_destroy   (EV_A);
#endif
#if EV_USE_PORTif (backend == EVBACKEND_PORT  ) port_destroy   (EV_A);
#endif
#if EV_USE_KQUEUEif (backend == EVBACKEND_KQUEUE) kqueue_destroy (EV_A);
#endif
#if EV_USE_EPOLLif (backend == EVBACKEND_EPOLL ) epoll_destroy  (EV_A);
#endif
#if EV_USE_POLLif (backend == EVBACKEND_POLL  ) poll_destroy   (EV_A);
#endif
#if EV_USE_SELECTif (backend == EVBACKEND_SELECT) select_destroy (EV_A);
#endif

个人认为,可以在各个模型的初始化中,将其对应的销毁函数指针赋值给一个叫backend_destory的变量。这样上述代表就可以变成一行了。

结合《libev源码解析——调度策略》的内容,我们可以用下图表达出libev运转的大体流程。

针对上图,可能有人会问:为什么backend_poll函数需要指定超时?我们让其一直等待到有事件发生不是更好么?

还有人会问:“符合条件的监视器”是否可以表述为“本次触发事件对应的监视器”?

对于这些问题,我们将在之后章节给出答案。

libev源码解析——I/O模型相关推荐

  1. libev源码解析——定时器原理

    本文将回答<libev源码解析--I/O模型>中抛出的两个问题.(转载请指明出于breaksoftware的csdn博客) 对于问题1:为什么backend_poll函数需要指定超时?我们 ...

  2. libev源码解析——监视器(watcher)结构和组织形式

    在<libev源码解析--总览>中,我们介绍了libev的一些重要变量在不同编译参数下的定义位置.由于这些变量在多线程下没有同步问题,所以我们将问题简化,所提到的变量都是线程内部独有的,不 ...

  3. libev源码解析——定时器监视器和组织形式

    我们先看下定时器监视器的数据结构.(转载请指明出于breaksoftware的csdn博客) /* invoked after a specific time, repeatable (based o ...

  4. libev源码解析——调度策略

    在<libev源码解析--监视器(watcher)结构和组织形式>中介绍过,监视器分为[2,-2]区间5个等级的优先级.等级为2的监视器最高优,然后依次递减.不区分监视器类型和关联的文件描 ...

  5. libev源码解析——总览

    libev是个非常优秀的基于事件的循环库,很多开源软件,比如nodejs就是使用其实现基础功能.本系列将对该库进行源码分析.(转载请指明出于breaksoftware的csdn博客) 不知道是被墙了还 ...

  6. libev 源码解析

    一  libev简介 libev是一个轻量级的事件通知库,具备支持多种事件通知能力,通过对libev的源码的阅读,可以清楚了解事件通知实现内部机制. 二 核心数据结构 在libev中关键的数据结构是, ...

  7. 谷歌BERT预训练源码解析(二):模型构建

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_39470744/arti ...

  8. php 框架源码分析,Laravel框架源码解析之模型Model原理与用法解析

    本文实例讲述了Laravel框架源码解析之模型Model原理与用法.分享给大家供大家参考,具体如下: 前言 提前预祝猿人们国庆快乐,吃好.喝好.玩好,我会在电视上看着你们. 根据单一责任开发原则来讲, ...

  9. spring源码解析系列之事件驱动模型架构

    2019独角兽企业重金招聘Python工程师标准>>> 说在前面 本文转自"天河聊技术"微信公众号 为什么要去研究spring源码,我认为java最NX的就是我写 ...

最新文章

  1. 一.Linq to JSON是用来干什么的?
  2. android lottie字体json,lottie-android
  3. 第八届育才杯机器人比赛_赛场、名单公布!南海区第八届“献血者杯”羽毛球公开赛“羽”你相约本周六...
  4. error C2220: 警告被视为错误 - 没有生成“object”文件
  5. MySQL FailOver(官方自带,free)
  6. python所有软件-python
  7. 猎隼涉密计算机安全,[原创]如何干掉《“猎隼”涉密计算机上网监察取证系统》...
  8. 安卓对讲机安装滔滔对讲黑屏起麦黑屏对讲设置
  9. OpenCms8.5 安装
  10. python怎么识别拼音-python+拼音
  11. Elasticsearch实战 | 必要的时候,还得空间换时间!
  12. 二级造价师课件网课下载,二级造价工程师考试时间报考条件公布!
  13. 去掉mysql u0000_js对于\u0000的处理
  14. VA虚拟应用匠心独妙,细节的精彩
  15. 期货价格怎么算出来的?
  16. JavaScript手机号码号段校验
  17. 基于JAVAEE的网络电子相册管理系统的设计与实现
  18. Word文档输入文字后面字消失怎么办?
  19. 项目之需求原来如此重要
  20. 项目学习记录(四)--基于图像检测的AR语文识字应用

热门文章

  1. 设置最大值_电机变频器参数设置不当会怎样
  2. 使用Python,dlib,OpenCV在实时的视频流中进行面部标志检测
  3. 2017icpc沈阳 G Infinite Fraction Path BFS+剪枝
  4. HDU 3306 Another kind of Fibonacci 矩阵快速幂
  5. HDU - 5876 Sparse Graph 2016 ACM/ICPC 大连网络赛 I题 bfs+set+补图最短路
  6. 自定义国内maven镜像包设置settings.xml
  7. 解决微信H5获取SDK授权报错提示errMsg: “config:fail,Error: 系统错误,错误码:63002,invalid signature [20200908 22:17:17][]“
  8. 在Ubuntu 16.04.5 LTS上安装pygame模块
  9. OpenCV和Python动手操作计算机视觉学习教程
  10. 在Unity中制作4种不同的游戏