试用libevent的事件触发
2012-05-24 22:31
330 查看
随着nginx,nodejs,Lua等技术大放异彩的时候,我们的程序设计习惯也在不断地改变中,现在什么都需要“异步”,做不到异步就和别人有差距了。看来教材上基于多进程多线程的模型等等远远不能满足现在互联网项目的需求。
我们知道不同操作系统,不同底层内核对于IO的事件驱动模型是不一样的,有poll,select,windows select,epoll,kqueue等多种选择。nginx服务器对于这些IO多路选择都做了很好的封装,我看libevent库也是对它们做了封装,就先来使用一下libevent库,感受它的事件触发的魅力。
首先是创建一个“事件”的方式:
下面是创建“event”的代码,我这里用“键盘输入”作为监听的描述符(方便演示),当程序运行时如果不输入内容,则等待五秒超时会触发cb_func函数,如果5秒内有键盘输入且回车,则描述符可读立即触发cb_func函数。
我们的程序是通过event_base_dispatch函数进入事件循环的,类似的进入循环的函数还有event_base_loop,后者相当于增强版dispatch,可以设置具体的循环方式。
libevent还提供了event_base_loopexit和event_base_loopbreak函数用以跳出事件循环。
查看libevent的官方首页,发现除了memcache是基于libevent库做的开发外,大名鼎鼎的chromium浏览器的Unix和mac版本也是基于libevent事件驱动库的。以后写一些底层的服务可以考虑使用它,毕竟自己维护一个异步非阻塞IO的框架还是异常麻烦的。
我在网上搜集了一个基于libevent的http库实现的简单的“web服务器”代码,在vc2010下配置运行成功,下载地址http://dl.dbank.com/c079f7ytkk
我们知道不同操作系统,不同底层内核对于IO的事件驱动模型是不一样的,有poll,select,windows select,epoll,kqueue等多种选择。nginx服务器对于这些IO多路选择都做了很好的封装,我看libevent库也是对它们做了封装,就先来使用一下libevent库,感受它的事件触发的魅力。
首先是创建一个“事件”的方式:
#include<event2\event.h> #include<stdio.h> #pragma comment(lib,"ws2_32.lib") static void discard_log(int severity, const char *msg) { //自定义记录日志 } int main(int argc, wchar_t* argv[]) { //替换记录日志的默认函数 event_set_log_callback(discard_log); //设置一个新的事件,设置配置信息 struct event_base *base; struct event_config *config = event_config_new(); //可供选择的方法有 select,poll,epoll,kqueue,devpoll,evport,win32 // //这里,不要使用kqueue event_config_avoid_method(config, "kqueue"); //特征值有:EV_FEATURE_ET,EV_FEATURE_O1,EV_FEATURE_FDS // //这里,需要支持边沿触发的后端 event_config_require_features(config, EV_FEATURE_ET); //选项有:EVENT_BASE_FLAG_NOLOCK,EVENT_BASE_FLAG_IGNORE_ENV, // EVENT_BASE_FLAG_STARTUP_IOCP,EVENT_BASE_FLAG_NO_CACHE_TIME // //这里,不要分配锁 event_config_set_flag(config, EVENT_BASE_FLAG_NOLOCK); base = event_base_new_with_config(config); event_config_free(config); if (base) { //... } else { return -1; } event_base_free(base); return 0; }
下面是创建“event”的代码,我这里用“键盘输入”作为监听的描述符(方便演示),当程序运行时如果不输入内容,则等待五秒超时会触发cb_func函数,如果5秒内有键盘输入且回车,则描述符可读立即触发cb_func函数。
#include<event.h> #include<stdio.h> //事件触发的回调函数 void cb_func(evutil_socket_t fd, short what, void *arg) { const char *data = (const char *)arg; printf("Got an event on socket %d:%s%s%s [%s]", (int) fd, (what&EV_TIMEOUT) ? " timeout" : "", (what&EV_READ) ? " read" : "", (what&EV_SIGNAL) ? " signal" : "", data); } void main_loop(evutil_socket_t fd) { struct event *ev; struct timeval five_seconds = {5,0};//超时5秒 struct event_base *base = event_base_new(); //创建一个event,设置为等待fd可读,记录超时,回调函数以及参数 ev = event_new(base, fd, EV_TIMEOUT|EV_READ, cb_func,(char *)"read event"); //将event挂在event_base中 event_add(ev, &five_seconds); event_base_dispatch(base); } int main(int argc, char* argv[]) { //键盘输入作为监听文件描述服 main_loop(0); return 0; }
我们的程序是通过event_base_dispatch函数进入事件循环的,类似的进入循环的函数还有event_base_loop,后者相当于增强版dispatch,可以设置具体的循环方式。
#define EVLOOP_ONCE 0x01 #define EVLOOP_NONBLOCK 0x02 #define EVLOOP_NO_EXIT_ON_EMPTY 0x04 int event_base_loop(struct event_base *base, int flags);
libevent还提供了event_base_loopexit和event_base_loopbreak函数用以跳出事件循环。
查看libevent的官方首页,发现除了memcache是基于libevent库做的开发外,大名鼎鼎的chromium浏览器的Unix和mac版本也是基于libevent事件驱动库的。以后写一些底层的服务可以考虑使用它,毕竟自己维护一个异步非阻塞IO的框架还是异常麻烦的。
我在网上搜集了一个基于libevent的http库实现的简单的“web服务器”代码,在vc2010下配置运行成功,下载地址http://dl.dbank.com/c079f7ytkk
相关文章推荐
- 鼠标悬停、事件触发试用,及信号发送
- 鼠标悬停、事件触发试用,及信号发送
- libevent evsignal_new() 信号事件回调函数未被触发。
- 鼠标悬停、事件触发试用,及信号发送
- libevent使用event事件触发服务端实例
- Web前端性能优化——高频触发事件的防抖
- jquery+javascript触发a标签的点击事件
- VC MFC 窗口最大化、最小化所触发的事件
- 解决内部元素onMouseOver/onMouseOut事件冒泡触发父元素的相应事件
- 程序添加JComboBox的item也能触发itemStateChanged事件吗
- jquery_trigger() 2个用法(自定义事件和触发2个作用)
- webkit 内核浏览器,<img>异步加载相同URL,不触发load事件的BUG
- JQuery弹出层中的服务器端Button事件不触发
- ASP.NET按钮button调用JavaScript函数验证,然后再触发button事件
- iphone 在电话来的时候会 触发事件
- jQuery 双击事件(dblclick)时,不触发单击事件(click)
- js利用trigger和bind实现自定义事件的定义和触发
- js实现浏览器窗口大小被改变时触发事件的方法
- js获取触发事件元素的坐标
- Asp.Net客户端触发服务器端事件及_dopostback