libev事件库
2017-02-21 00:00
267 查看
以Nginx为代表,IO事件+定时器组成的事件驱动构成了现在高性能网络处理的基础,libev库是继libevent之后又一个事件库,为编写事件驱动程序提供底层的封装,相比libevent更加精简,没有附加额外的复杂功能。
下面是一个简单的例子。
程序启动时设置定时器,5秒后定时器启动输出“Hello World!”,之后每隔2秒输出一次。
对每个事件都要有一个结构体,储存事件相关的信息,对于定时器事件,结构体为ev_timer, 启动一个定时器相当简单
定义ev_timer结构体。
定时器设置,主要是回调函数,首次触发时间和之后的出发间隔。
通过ev_timer_start将定时事件加入到事件循环中。
随时可以通过ev_timer_stop注销事件。
下面的例子中,程序启动1秒后输出“Hello World!”,之后间隔每个增加一秒,输出4次后结束。
事件驱动框架中最重要的还是IO事件的处理,相关的API与定时器事件类似,不过IO事件会区分读和写。下面是一个简单的例子。
这是一个IO事件的例子,程序启动后等待用户输入,对于可读事件(revents & EV_READ),fgets获取用户输入,对于可写事件(revents & EV_WRITE),进行输出。
这里为了简单使用是终端的输入输出操作,实际编程中libev库更多的是用来处理网络IO事件。
程序处理中,大多数IO事件都会设置超时机制,避免无限期等待下去,尤其是网络IO中,建立连接,读取数据,发送数据都要设置超时时间以免已经破坏的连接一直占用系统资源。对这种情况需要将定时器事件与IO事件结合起来。IO事件超时后执行定时器事件,将IO事件撤销,同样IO事件执行成功要将定时器事件撤销。为此需要一个结构体存放IO事件和定时器事件的信息。
在ev_io和ev_timer等所有事件的结构体中都有一个void指针,可以存储相应的数据。
如下面的例子,5秒后如果终端没有接受到任何输入就会注销IO事件。
下面是一个简单的例子。
#include<stdio.h> #include<ev.h> void timer_action(struct ev_loop *loop, ev_timer *w, int e) { printf("Hello World!\n"); } int main(int argc, char *argv[]) { struct ev_loop *loop = ev_default_loop(0); ev_timer w; ev_timer_init(&w, timer_action, 5, 2); ev_timer_start(loop, &w); ev_run(loop, 0); return 0; }
程序启动时设置定时器,5秒后定时器启动输出“Hello World!”,之后每隔2秒输出一次。
对每个事件都要有一个结构体,储存事件相关的信息,对于定时器事件,结构体为ev_timer, 启动一个定时器相当简单
定义ev_timer结构体。
定时器设置,主要是回调函数,首次触发时间和之后的出发间隔。
通过ev_timer_start将定时事件加入到事件循环中。
随时可以通过ev_timer_stop注销事件。
下面的例子中,程序启动1秒后输出“Hello World!”,之后间隔每个增加一秒,输出4次后结束。
#include<stdio.h> #include<ev.h> int count = 0; int timeout = 1; void timer_action(struct ev_loop *loop, ev_timer *w, int e) { printf("Hello World!\n"); count += 1; if (count > 3) { ev_timer_stop(loop, w); return; } timeout += 1; ev_timer_stop(loop, w); ev_timer_set(w, timeout, 0); ev_timer_start(loop, w); } int main(int argc, char *argv[]) { struct ev_loop *loop = ev_default_loop(0); ev_timer w; ev_timer_init(&w, timer_action, 1, 0); ev_timer_start(loop, &w); ev_run(loop, 0); return 0; }
事件驱动框架中最重要的还是IO事件的处理,相关的API与定时器事件类似,不过IO事件会区分读和写。下面是一个简单的例子。
#include<stdio.h> #include<ev.h> ev_io stdin_watcher; char buf[4096]; void io_action(struct ev_loop *loop, ev_io *w, int revents) { if (revents & EV_READ) { fgets(buf, 4096, stdin); ev_io_stop(loop, w); ev_io_set(w, 0, EV_WRITE); ev_io_start(loop, w); } else if (revents & EV_WRITE) { printf("Input:%s\n", buf); ev_io_stop(loop, w); } return; } int main(void) { struct ev_loop *loop = ev_default_loop(0); ev_io_init(&stdin_watcher, io_action, /* STDIN_FILENO */ 0, EV_READ); ev_io_start(loop, &stdin_watcher); ev_run(loop, 0); return 0; }
这是一个IO事件的例子,程序启动后等待用户输入,对于可读事件(revents & EV_READ),fgets获取用户输入,对于可写事件(revents & EV_WRITE),进行输出。
这里为了简单使用是终端的输入输出操作,实际编程中libev库更多的是用来处理网络IO事件。
程序处理中,大多数IO事件都会设置超时机制,避免无限期等待下去,尤其是网络IO中,建立连接,读取数据,发送数据都要设置超时时间以免已经破坏的连接一直占用系统资源。对这种情况需要将定时器事件与IO事件结合起来。IO事件超时后执行定时器事件,将IO事件撤销,同样IO事件执行成功要将定时器事件撤销。为此需要一个结构体存放IO事件和定时器事件的信息。
在ev_io和ev_timer等所有事件的结构体中都有一个void指针,可以存储相应的数据。
如下面的例子,5秒后如果终端没有接受到任何输入就会注销IO事件。
#include<stdio.h> #include<ev.h> struct io_timer_struct { ev_io io; ev_timer timer; char buf[4096]; }; void io_action(struct ev_loop *loop, ev_io *w, int revents) { struct io_timer_struct *s = (struct io_timer_struct *)w->data; if (revents & EV_READ) { fgets(s->buf, 4096, stdin); ev_io_stop(loop, w); ev_io_set(w, 0, EV_WRITE); ev_io_start(loop, w); } else if (revents & EV_WRITE) { printf("Input:%s\n", s->buf); ev_io_stop(loop, w); } ev_timer_stop(loop, &s->timer); return; } void timer_action(struct ev_loop *loop, ev_timer *w, int revents) { struct io_timer_struct *s = (struct io_timer_struct *)w->data; ev_io_stop(loop, &s->io); return; } int main(void) { struct ev_loop *loop = ev_default_loop(0); struct io_timer_struct s; memset(&s, 0, sizeof(s)); s.io.data = &s; ev_io_init(&s.io, io_action, 0, EV_READ); ev_io_start(loop, &s.io); s.timer.data = &s; ev_timer_init(&s.timer, timer_action, 5, 0); ev_timer_start(loop, &s.timer); ev_run(loop, 0); return 0; }
相关文章推荐
- 详解Javascript事件驱动编程
- 深入理解javaScript中的事件驱动
- window.addeventjs事件驱动函数集合addEvent等
- 快速掌握Node.js事件驱动模型
- 浅谈javascript基础之客户端事件驱动
- Node.js中的事件驱动编程详解
- Nginx学习笔记之事件驱动框架处理流程
- Spring4 版 eventbus 事件通信 事件驱动 介绍
- #分布式系统架构之# 事件驱动模式以及与之匹配的长时间处理过程讨论
- PHP测试框架Peridot-支持BDD
- libev 学习笔记之timer实现原理
- libev 学习笔记之主体事件循环
- libev 学习笔记之源码树
- libev 学习笔记
- js事件驱动
- Mac OS X 10.9 安装gevent
- libev学习笔记(二)——ev_io
- 详解Spring事件驱动模型-Spring中ApplicationContext对事件的支持
- node.js(一)包管理、缓冲区、事件驱动、定时器
- libev socket 的一个服务器