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
转载于:https://blog.51cto.com/xzq2000/1767388
libevent学习笔记相关推荐
- libevent学习笔记六:libevent核心事件event
libevent学习笔记六:libevent核心事件event 前面对reactor模式.事件处理流程.libevent源代码结构等有了高层的认识后,接下来将详细介绍libevent的核心结构even ...
- 【Libevent】Libevent学习笔记(三):事件循环
00. 目录 文章目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. eve ...
- 【Libevent】Libevent学习笔记(一):简介和安装
00. 目录 文章目录 00. 目录 01. libevent简介 02. Libevent的好处 03. Libevent的安装和测试 04. Libevent成功案例 05. 参考资料 01. l ...
- libevent学习笔记 一、基础知识
一.libevent是什么 libevent是一个轻量级的开源的高性能的事件触发的网络库,适用于windows.linux.bsd等多种平台,内部使用select.epoll.kqueue等系统调用管 ...
- 【传智播客】Libevent学习笔记(三):事件循环
目录 00. 目录 01. event_base_loop函数 02. event_base_dispatch函数 03. event_base_loopexit函数 04. event_base_l ...
- 【传智播客】Libevent学习笔记(一):简介和安装
目录 00. 目录 01. libevent简介 02. Libevent的好处 03. Libevent的安装和测试 04. Libevent成功案例 00. 目录 @ 01. libevent简介 ...
- libevent 学习笔记
一.参考 libevent Libevent深入浅出 - <Libevent 深入浅出> - 书栈网 · BookStack libevent 之 event config的相关函数介绍_ ...
- 【Libevent】Libevent学习笔记(二):创建event_base
00. 目录 文章目录 00. 目录 01. 简介 02. 创建默认的event_base 03. 创建复杂的event_base 3.1 event_config_new函数 3.2 event_b ...
- 【传智播客】Libevent学习笔记(四):事件event
目录 00. 目录 01. 事件概述 02. 创建事件 03. 事件的标志 04. 事件持久性 05. 超时事件 06. 信号事件 07. 设置不使用堆分配的事件 08. 事件的未决和非未决 09. ...
最新文章
- Blender+SP+UE5游戏艺术工作流程学习
- 说说docker run的--detach
- redis维护问题总结
- 树的存储结构-双亲表示法
- 数电与模电的根本区别 转
- Web前端开发培训就业前景好不好?
- Linux/CentOS/Ubuntu查看文件内容命令总结
- RPM方式安装MySQL5.5.48 (Aliyun CentOS 7.0 卸载MySQL5.7)
- 利用度盘直链解析网页及XDOWN高速下载百度网盘分享资源
- 计算机电源24针,ATX电源20针和24针接口定义
- 移动互联网时代的 Google,战略指向笔记本
- 金彩教育:如何提升自然流量
- 【MongoDB】使用$lookup做多表关联处理
- 时势造英雄,快影成长启示录
- 应用于大数据分析的工作流调度系统
- 微软官方建议的28条代码优化方案
- 投影仪对和电视哪个对眼睛好?有区别吗?
- 虚拟机的虚拟化如何开启?
- 如何构建用户画像,给用户打“标签”?
- 潍坊OA:通达OA 2015版正式发布