博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
libev
阅读量:5043 次
发布时间:2019-06-12

本文共 2663 字,大约阅读时间需要 8 分钟。

libev是一个**事件驱动库**,它需要循环探测事件是否发生,在Linux上实际是封装了epoll等系统调用。

其循环过程由ev_loop( )函数设置,循环体是ev_loop结构。

//创建事件循环void ev_loop( ev_loop* loop, int flags )

libev支持多种事件类型,常用的如I/O,定时器,信号等。详细的可以去看官网教程的WATCHER TYPES章节。

每种事件都有具体结构来表示,如ev_io表示一个I/O事件。事件通过ev_io_init()函数初始化。

//初始化一个事件void ev_io_init(ev_io *io, callback, int fd, int events)

初始化内容包括了,探测的fd,事件类型,回调函数等。如初始化一个fdx的可读事件:

ev_io_init(accept_event, acceept_callback, fdx, EV_READ);

 

普通网络程序中,一般阻塞在accept(socket_fd),在连接到达后返回一个connect_fd继续等待。而事件驱动模型中,则变为探测socket_fd是否可读。在callback回调中去执行accept,不再阻塞。

现在我们要做的只是将初始化好的accept_event这个事件加入到事件循环中去。

将事件添加到事件循环,或将事件从事件循环删去,是通过ev_io_start()和ev_io_stop函数完成(这里示例I/O事件):

void ev_io_start( ev_loop *loop, ev_io* io ) void ev_io_stop( EV_A_* )

虽然很多细节未考虑,但一个简单的事件驱动的服务器模型已经有了。其中屏蔽了很多裸写epoll要处理的细节。

简单总结下步骤:

1、创建一个事件循环

struct ev_loop *loop = EV_DEFAULT;

2、初始化一个待探测的事件,这个事件由fd(I/O为例),回调函数,事件类型(读/写)等组成

ev_io stdin_watcher;

ev_io_init (&stdin_watcher, callback, /*STDIN_FILENO*/ 0, EV_READ);

3、将事件加入到事件循环

ev_io_start (loop, &stdin_watcher);

4、启动事件循环

ev_run (loop, 0);

我们可以随时向事件循环中加入事件,或从中删除某事件。

完整示例:

// a single header file is required   #include 
#include
// for puts // every watcher type has its own typedef'd struct // with the name ev_TYPE ev_io stdin_watcher; ev_timer timeout_watcher; // all watcher callbacks have a similar signature // this callback is called when data is readable on stdin static void stdin_cb (EV_P_ ev_io *w, int revents) { puts ("stdin ready"); // for one-shot events, one must manually stop the watcher // with its corresponding stop function. ev_io_stop (EV_A_ w); // this causes all nested ev_run's to stop iterating ev_break (EV_A_ EVBREAK_ALL); } // another callback, this time for a time-out static void timeout_cb (EV_P_ ev_timer *w, int revents) { puts ("timeout"); // this causes the innermost ev_run to stop iterating ev_break (EV_A_ EVBREAK_ONE); } int main (void) { // use the default event loop unless you have special needs struct ev_loop *loop = EV_DEFAULT; // initialise an io watcher, then start it // this one will watch for stdin to become readable ev_io_init (&stdin_watcher, stdin_cb, /*STDIN_FILENO*/ 0, EV_READ); ev_io_start (loop, &stdin_watcher); // initialise a timer watcher, then start it // simple non-repeating 5.5 second timeout ev_timer_init (&timeout_watcher, timeout_cb, 5.5, 0.); ev_timer_start (loop, &timeout_watcher); // now wait for events to arrive ev_run (loop, 0); // break was called, so exit return 0; }

 

转载于:https://www.cnblogs.com/gm-201705/p/9863908.html

你可能感兴趣的文章
BZOJ 2338 HNOI2011 数矩形 计算几何
查看>>
关于页面<!DOCTYPE>声明
查看>>
【AS3代码】播放FLV视频流的三步骤!
查看>>
C++标准库vector使用(更新中...)
查看>>
cocos2d-x 2.2.6 之 .xml文件数据读取
查看>>
枚举的使用
查看>>
BZOJ 1531 二进制优化多重背包
查看>>
BZOJ 2324 (有上下界的)费用流
查看>>
python3基础06(随机数的使用)
查看>>
Zookeeper系列(二)特征及应用场景
查看>>
【HTTP】Fiddler(三)- Fiddler命令行和HTTP断点调试
查看>>
Spring Boot使用Druid和监控配置
查看>>
poi 处理空单元格
查看>>
Android 内存泄漏优化总结
查看>>
luogu4849 寻找宝藏 (cdq分治+dp)
查看>>
Spring Cloud微服务笔记(五)Feign
查看>>
C语言键盘按键列表
查看>>
Codeforces Round #374 (Div. 2)
查看>>
oracle数据类型
查看>>
socket
查看>>