Libev源码解析
来源:互联网 发布:如何评价中国股市知乎 编辑:程序博客网 时间:2024/06/06 00:58
最近在看libev源码,算是对libev的源码有个比较清晰的了解。
总共分3部分来介绍libev.
1 Libev是什么
Libev是基于Reactor模式的一个高性能,支持高并发的事件库。它本身不仅支持IO,timer(定时器),还支持signal, fork等。并且它短小精悍 ,并且C语言实现。
2. Libev重要的数据结构
只有了解并且熟悉了Libev的基本数据结构,才能更顺利的理解Libev怎么实现的事件库的。
基类ev_watcher
typedef struct ev_watcher { int active; // 激活标志 int pending; // 等待事件数 int priority; //优先级 void* data; // 回调函数 void (*cb)(struct ev_loop* loop, struct ev_watcher* w, int revent);} ev_watcher;
ev_watcher_list
typedef struct ev_watcher_list { int active; int pending; int priority; void* data; void (*cb)(struct ev_loop* loop, struct ev_watcher_list* w, int revent); struct ev_watcher_list* next;} ev_watcher_list;ev_watcher_time
typedef double ev_tstamp;typedef struct ev_watcher_time { int active; // 激活标志 int pending; // 等待事件数 int priority; //优先级 void* data; // 回调函数 void (*cb)(struct ev_loop* loop, struct ev_watcher_time* w, int revent); ev_tstamp at;} ev_watcher_time;ev_timer
typedef struct ev_timer { int active; // 激活标志 int pending; // 等待事件数 int priority; //优先级 void* data; // 回调函数 void (*cb)(struct ev_loop* loop, struct ev_watcher_time* w, int revent); ev_tstamp at; // 在"at"之后发生timeout事件 ev_tstamp repeat; // 在"repeat"之后触发timeout事件,循环} ev_timer;ev_io
typedef struct ev_io { int active; int pending; int priority; void* data; void (*cb)(struct ev_loop *loop, struct ev_io *w,int revents); struct ev_watcher_list *next; int fd;// 文件描述符 int events;// 事件類型} ev_io;
typedef struct ev_signal { int active; int pending; int priority; void* data; void (*cb)(struct ev_loop *loop, struct ev_signal *w,int revents); struct ev_watcher_list *next; int signum; // 信号量like SIGxxx} ev_signal;ev_prepare
/* invoked for each run of the mainloop, just before the blocking call *//* you can still change events in any way you like *//* revent EV_PREPARE */typedef struct ev_prepare { int active; int pending; int priority; void* data; void (*cb)(struct ev_loop *loop, struct ev_prepare *w,int revents);} ev_prepare;ev_check
/* invoked for each run of the mainloop, just after the blocking call *//* revent EV_CHECK */typedef struct ev_check { int active; int pending; int priority; void* data; void (*cb)(struct ev_loop *loop, struct ev_check *w,int revents);} ev_check;ev_loop:
struct ev_loop { ev_tstamp ev_rt_now; #define ev_rt_now ((loop)->ev_rt_now) #define VAR(name,decl) decl; #include "ev_vars.h" // 包含众多成员 #undef VAR};ev_loop的成员:
ev_tstamp now_floor; /* last time we refreshed rt_time */ ev_tstamp mn_now; // 当前单调时间,系统开机时间 ev_tstamp rtmn_diff; // difference realtime - monotonic time unsigned int origflags;int backend; //epoll 、 kqueue 、 poll 、 select 、 port 标记int activecnt;// 激活事件总数int backend_fd;// 对于 epoll, 为 epoll_create 返回的描述符 int * fdchanges;// 事件队列int fdchangemax;// 当前最大事件数 int fdchangecnt;// 事件数ANPENDING *pendings [NUMPRI];// 待处理队列int pendingmax [NUMPRI];// 当前最大等待事件的数量 int pendingcnt [NUMPRI];// 记录每个优先级的数量
ANFD:
typedef struct{ ev_watcher_list* head; //监听者链表 unsigned char events; //监听的事件 unsigned char reify;//状态位 用来表示具体是EV_ANFD_REIFY还是EV_IOFDSET unsigned char emask;//epoll用来保存内核mask的值 unsigned char unused;//同名字#if EV_USE_EPOLL unsigned int egen;//#endif#if EV_SELECT_ISWINSOCKET || EV_USE_IOCP SOCKET handle;//#endif#if EV_USE_IOCP OVERLAPPED or,ow;//#endif} ANFD;ANPENDING
typedef struct { ev_watcher* w; int events;} ANPENDING;堆结构的节点(用于管理定时器)
typedef struct { ev_tstamp at; ev_watcher_time* w;} ANHE;开始前准备:
ev_init(ev_TYPE *watcher, callback)
ev_io_init(ev_io *, callback, int fd, int events)
Fd: EV_READ, EV_WRITEor EV_READ | EV_WRITE
ev_io_set(ev_io *, int fd, int events)
ev_timer_init(ev_timer *, callback, ev_tstamp after, ev_tstamp repeat)
ev_timer_set(ev_timer *, ev_tstamp after, ev_tstamp repeat)
3. ev_run执行流程
通过epoll_poll之后,已经将就绪的IO事件放入pendings数组中,随后需要放入的是最小堆中的超时watcher。超时watcher放入过程如下:
在处理最小堆的watcher时,会先讲watcher放入rfeeds数组中,随后再逆序从rfeed中事件放入pendings数组中。这两个数组的关系如下:
在收集完所有的watcher之后,进入EV_INVOKE_PENDING的流程中,也就是从pendings数组中按照优先级顺序从数组中逆序去除watcher进行invoke_cb的回调。
具体过程如下:
其中pending数组和EV_INVOKE_PEINDING的过程关系图如下:
4 参考文献:
- Libev源码解析
- ss-libev 源码解析udp篇 (1)
- ss-libev 源码解析udp篇 (2)
- ss-libev 源码解析udp篇 (3)
- ss-libev 源码解析udp篇 (4)
- libev源码解析——总览
- libev源码解析——调度策略
- libev源码解析——定时器原理
- ss-libev 源码解析local篇(4): server_recv_cb之STAGE_STREAM
- libev源码解析——I/O模型
- libev源码解析——定时器监视器和组织形式
- libev源码分析1
- libev 源码浅析
- libev ev_io源码分析
- libev源码分析
- libev源码解读
- libev源码分析libev数据结构整理
- libev源码分析libev数据结构整理
- BestCoder zxa and set
- 内存堆栈篇
- linux基本命令(24)——linux文件类型与扩展名
- 空间句法 资料总结
- 深入理解java内存模型(三)——顺序一致性
- Libev源码解析
- 路在何方
- 微信分享闪退问题分析及解决
- 白盒与黑盒到底什么?
- 算法篇
- String类的相关方法介绍
- intellij配置hibernate自动生成hbm.xml文件
- RecyclerView通用适配器
- [Java] 贪吃蛇 V1.0