libevent学习笔记

libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台。

libevent在linux上实现是使用epoll机制的。

平时在代码里使用的是epoll,觉得没有windows完成端口方便,需要自己去实现一些功能。
公司常用的linux自带libevent版本1.1,现在最新的版本是2.0,但是刚刚推出,头文件很多都改变了,最成熟的库是1.4。
http://monkey.org/~provos/libevent/

使用回调函数来实现自定义功能。
一个简单的网络事件
void fifo_read(int fd, short event, void *arg)
{
 struct event *ev = (struct event *)arg;
 /* 重新安排事件 */
 event_add(ev, NULL);
 /* 读socket */
 len = read(fd, buf, sizeof(buf) - 1);
}

main()
{
 ……
 /* 初始化事件 */
 event_init();
 /* 设置事件为可读,回调函数fifo_read */
 event_set(&evfifo, socket, EV_READ, fifo_read, &evfifo);
 /* 添加事件,没有超时时间 */
 event_add(&evfifo, NULL);
 /* 进入libevent主循环 */
 event_dispatch();
 ……
}

一个简单的信号处理
int called = 0;
static void signal_cb(int fd, short event, void *arg)
{
 struct event *signal = (struct event *)arg;
 printf("%s: got signal %d\n", __func__, EVENT_SIGNAL(signal));
 /* 调用2次就销毁事件 */
 if (called >= 2)
  event_del(signal);
 called++;
}

int main (int argc, char **argv)
{
 ……
 struct event signal_int;
 /* 初始化,比较早期的例子代码,这里变成了 event_base_new,而不是event_init()*/
 struct event_base* base = event_base_new();
 /* 初始化事件 */
 event_set(&signal_int, SIGINT, EV_SIGNAL|EV_PERSIST, signal_cb,&signal_int);
 event_base_set(base, &signal_int);
 event_add(&signal_int, NULL);
 event_base_dispatch(base);
 event_base_free(base);
 ……
}

一个简单的超时例子
int lasttime;

static void timeout_cb(int fd, short event, void *arg)
{
 struct timeval tv;
 struct event *timeout = (struct event *)arg;
 int newtime = time(NULL);
 printf("%s: called at %d: %d\n", __func__, newtime,
     newtime - lasttime);
 lasttime = newtime;
 evutil_timerclear(&tv);
 tv.tv_sec = 2;
 event_add(timeout, &tv);
}

int
main (int argc, char **argv)
{
 ……
 struct event timeout;
 struct timeval tv; 
 /* 初始化*/
 event_init();
 /* 一个封装,等同于 event_set(timeout,-1,0,timeout_cb,&timeout) */
 evtimer_set(&timeout, timeout_cb, &timeout);
 evutil_timerclear(&tv);
 tv.tv_sec = 2;
 event_add(&timeout, &tv);
 lasttime = time(NULL); 
 event_dispatch();
 ……
}
在定时器上使用了最小二叉堆的方式,提高了效率。

http服务支持
void generic_handler(struct evhttp_request *req, void *arg)
{
 struct evbuffer *buf;
 buf = evbuffer_new();
 if (buf == NULL)
  err(1, "failed to create response buffer");
 evbuffer_add_printf(buf, "Requested: %s", evhttp_request_uri(req));
 evhttp_send_reply(req, HTTP_OK, "OK", buf);
 evbuffer_free(buf);
}

int main(int argc, char **argv)
{
 ……
 struct evhttp *httpd;
 event_init();
 httpd = evhttp_start("0.0.0.0", 8080);
 /* 用一个回调函数来支持get中的 "/specific". */
 /* evhttp_set_cb(httpd, "/specific", another_handler, NULL); */
 /* 用一个回调函数来支持其他的请求 */
 evhttp_set_gencb(httpd, generic_handler, NULL);
 event_dispatch();
 evhttp_free(httpd);
 ……
}
libevent对于连接中有可能长时间阻塞的任务处理,那么还需要自己来加点处理,并没有很现成的多线程处理模式,而且看http处理的源码,并不支持多线程安全。

阅读中对epoll重新温习了一下。
早期用epoll编码的时候发现过,当有压力的时候,明明抓包收到了2个udp包,但是epoll只出发了一次事件,只有再接收一次报文的时候才会接收处理上次的udp包。然后发现是增加参数变成高速模式的原因,修改为事件中循环读取到无数据为止。

“EPOLLLT和EPOLLET两种触发模式,LT是默认的模式,ET是“高速”模式。LT模式下,只要这个fd还有数据可读,每次epoll_wait都会返回它的事件,提醒用户程序去操作,而在ET(边缘触发)模式中,它只会提示一次,直到下次再有数据流入之前都不会再提示了,无论fd中是否还有数据可读。所以在ET模式下,read一个fd的时候一定要把它的buffer读光,也就是说一直读到read的返回值小于请求值,或者遇到EAGAIN错误。”

libevent的epoll使用的是EPOLLLT,效率并不算太高。
感觉没有太多自动的东西,比如多线程处理连接,或者自动淘汰syn但是没有send的链接等等,毕竟只是个轻量级的lib库。

可以看这个网页,先是讨论了,判断syn超时的问题,然后讨论了模式的区别。

http://www.chinaunix.net/jh/23/813588.html

时间: 2024-10-28 10:42:03

libevent学习笔记的相关文章

libevent学习笔记-使用指导

windows下Code::Blocks建立GNU编译的工程: 1.需要添加如下头文件: D:\E\programing\levent-libevent\include D:\E\programing\levent-libevent\gnu\includeC:\Program Files\Dev-Cpp\MinGW32\include 2.需要添加如下静态库: ws2_32 kernel32 user32 gdi32 winspool shell32 ole32 oleaut32 uuid co

Libevent 学习笔记 (1)——Libevent 2.0安装与简单示例

今天开始学习Libevent .Libevent 是开源社区的一款高性能I/O框架库. 主要特点有: 1 跨平台: 2 统一事件源 3 线程安全 4 基于Reactor 今天主要进行了Libevent的安装,以及利用libevent框架编写一个间隔1s打印 Hello Libevent!信息的程序. 首先是安装: 1 下载libevent源码,下载地址http://libevent.org/.我下载的版本是2.0 stable版本,下载的文件格式是tar.gz包 2 进入刚下载得到的tar.gz

libevent学习笔记 一、基础知识

欢迎转载,转载请注明原文地址:http://blog.csdn.net/majianfei1023/article/details/46485705 一.libevent是什么 libevent是一个轻量级的开源的高性能的事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用select.epoll.kqueue等系统调用管理事件机制. 它被众多的开源项目使用,例如大名鼎鼎的memcached等. 特点: 事件驱动,高性能; 轻量级,专注于网络(相对于ACE); 开放源码

Libevent 学习笔记 (1)——Libevent 2.0安装与简单演示样例

今天開始学习Libevent . Libevent 是开源社区的一款高性能I/O框架库. 主要特点有: 1 跨平台. 2 统一事件源 3 线程安全 4 基于Reactor 今天主要进行了Libevent的安装,以及利用libevent框架编写一个间隔1s打印 Hello Libevent! 信息的程序. 首先是安装: 1 下载libevent源代码,下载地址http://libevent.org/.我下载的版本号是2.0 stable版本号.下载的文件格式是tar.gz包 2 进入刚下载得到的t

libevent学习笔记(参考libevent深度剖析)

最近自学libevent事件驱动库,参考的资料为libevent2.2版本以及张亮提供的<Libevent源码深度剖析> libevent好处之类的就不赘述了,libevent和libiop,redis等一样都是采用事件回调机制,这种模式 被称作Reactor模式.正常事件处理流程是应用程序调用某个接口触发某个功能,而Reactor模式需要 我们将这些接口和宿主指针(谁调用这些接口)注册在Reactor,在合适的时机Reactor使用宿主指针 调用注册好的回调函数. 一: Reactor基本知

[原创] linux课堂-学习笔记-目录及概况

本学习笔记基于:网易云课堂-linux课堂 课时1Centos 6.4安装讲解46:14 课时2Centos 6.4桌面环境介绍与网络连接04:30 课时3 Linux目录结构介绍及内核与shell分析37:19 课时4 Linux获得帮助_网络配置_合理关机64:23 课时5 Linux文件权限详解45:47 课时6Linux文件权限详解45:47 课时7目录显示个性操作与全局环境变量的使用与注意···43:25 课时8复制与远程复制_文件查找实例_文件内容查看的··57:49 课时9Linu

memcached学习笔记6--浅谈memcached的机制 以及 memcached细节讨论

附:请浅谈memcached的机制 答: ①基于C/S架构,协议比较简单 c/s架构,此时memcached为服务器端,我们可以使用如PHP,c++/c等程序连接memcached服务器. memcached的服务器客户端通信并不使用XML等格式,而使用简单的基于文本行的协议,因此通过telnet也能在memcached上保存.读取数据. ②基于libevent事件来处理的 libevent是一套垮平台的事件处理接口的封装,能够处理兼容包括这些操作系统: windows/Linux/BSD/So

游戏服务器学习笔记

linux命令行环境 linux常用命令用法,软件的安装,vim的用法,在特定的linux版本安装了epel源,学会用SSH配置公钥.私钥,通过SSH来远程登录linux主机,如在windows下用putty来远程登录linux主机. 版本控制工具 svn/git,git可以和gitlab配合使用. C/C++语言 python语言 学习python编程规范(PEP8),了解python的相关模块用法,如:django,twisted,yaml,json,pymongo,markdown,pyl

libevent学习__学习历程总结

The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regular timeouts. 环境搭建 下载: http