深入浅出libevent的使用(一)
来源:互联网 发布:sql with as 用法 编辑:程序博客网 时间:2024/05/07 20:46
导语:
对libevent源码分析的文章已经很多,在此不在重述原理,但从另外一个角度讲,知晓原理就是为了更好的使用libevent,本文通过介绍libevent中的mini-heap,socketpair以及对evbuffer的使用,展示libevent所依赖的几个基本数据结构
1. min-heap的使用
理解小根堆的原理和使用,对超时事件的理解比较有帮助,min-heap俗称小根堆,就是一个完全二叉树,根结点的数据比左节点大,比右节点也大,类似
在libevent中作为对超时事件的时间进行排序,根结点的时间最先超时这么个原理
- min-heap根结点的初始化:min_heap_ctor
- 删除根节点: min_heap_dtor
- min-heap的插入: min_heap_push
- min-heap的删除: min_heap_pop
示例如下:
min_heap_ctor(&heap); for(i = 0;i < 9; ++i) { inserted[i] = mm_malloc(sizeof(struct event)); set_random_timeout(inserted[i]); min_heap_push(&heap,inserted[i]); } min_heap_print(&heap); printf("heap size :%d\n",min_heap_size(&heap)); while(1) { e = min_heap_pop(&heap); if(!e) break; mm_free(e); } min_heap_dtor(&heap);
2. socketpair的使用
socketpair的使用场景,主要是在进程间的通信,或者线程间的通信,其原理在源码分析中已经分析的相当透彻,在libevent中的使用,主要是用来在子线程中有可读事件,可写事件,通知主线程,在使用场景中的其他用途,你完全可以发挥想象,socketpair实际上就是两个本地的套接字,在一个进程中监听读,在另外一个进程中写
- 创建socketpair的方法: evutil_socketpair
示例如下:
ret = evutil_socketpair(LOCAL_SOCKETPAIR_AF,SOCK_STREAM,0,fds); if( ret < 0 ) { printf("evutil_socketpair falt %d!",ret); return -1; } if( fork() ) { //parent process int count = 0; int val; close(fds[1]); while(1){ ++count; write(fds[0],&count,sizeof count); read(fds[0],&val,sizeof val); printf("recv data :%d\n",val); } }else{ //child process int val; close(fds[0]); while(1){ sleep(1); read(fds[1],&val,sizeof(val)); printf("recv data :%d\n",val); val = -val; write(fds[1],&val,sizeof val); } }
3. evbuffer的使用
evbuffer的作用顾名思义就是读写的缓冲区,这部分实现的好坏,实际上关乎一个网络组件的效率高低,所以evbuffer的实现,还是需要花时间去理解,不过使用起来还是蛮简单的,大部分的接口,可以参考event2/buffer.h,这里需要注意的是,当evbuffer在多线程环境下使用时首先要显式调用evthread_use_pthreads函数,并且要调用 evbuffer_enable_locking来初始化evbuffer中的锁,另外需要注意evbuffer是用链表形式实现的,一个节点写入数据会有空闲块,这个空闲块小于一定的阈值时,将创建写节点来写入数据,当节点数据很小时,会创建一个新节点,来容纳这个节点数据和新写入的数据
- evbuffer_new 创建evbuffer
- evbuffer_add 往evbuffer中添加数据
- evbuffer_remove 从evbuffer中拷贝数据并删除
- evbuffer_drain 直接删除数据
示例代码:
//写进程 while(1) { sprintf(message,message_s,++count); message_len = strlen(message); //写入数据 \n结尾 evbuffer_add(buf,message,message_len); length = evbuffer_get_length(buf); printf("thread write :%d\n",length); total += message_len; sleep(1); } //读进程 read_message = evbuffer_readln(buf,&read_message_len,EVBUFFER_EOL_CRLF); if (NULL != read_message) { printf("thread read :%s\n",read_message); length += read_message_len; }
完整参考:https://github.com/dengwenyi88/test_libevent/
结论:读者也可以在示例中使用更多的接口,加深使用libevent的理解,同时对源码实现的基本原理的理解有帮助,bufferevent的工作流程是依赖于,对event和event_base的进一步封装,在对套接字的读超时和写超时处理,就用到事件的超时处理,同时对socket的读监听事件和写监听事件,都涉及到event_base的基本原理,以及evbuffer中事件的回调处理
参考:
小根堆 http://blog.csdn.net/ganggexiongqi/article/details/7449970
libevent源码分析: http://blog.csdn.net/column/details/libevent-src.html
- 深入浅出libevent的使用(一)
- (一)libevent安装及简单的使用
- libevent(一):简单使用
- 学习使用libevent(一)
- libevent使用(一)-----基础配置
- libevent的使用
- libevent的使用(socket)
- libevent的使用
- libevent的使用(socket)
- libevent的使用
- 测试libevent的使用
- http libevent的使用
- libevent的使用
- Libevent的使用
- 使用libevent编写linux服务(一)
- 使用libevent编写linux服务(一)
- Libevent学习笔记(一):基本使用
- libevent的使用(socket)
- SQL Date 函数
- crontab 定时任务添加
- IIS8.5 ARR Rewrite 不缓存反向代理的网页
- 谈层组件layer封装网页消息提示
- zabbix3.2监控TCP状态
- 深入浅出libevent的使用(一)
- GPU编程语言选择(OpenCL、CUDA 与C++ AMP)
- Android中px与dip,sp与dip等的转换工具类
- Collection集合概览
- Android滑动冲突解决方法
- Android Studio中需要知道的那些Version
- quick-cocos调java函数异常报错
- cocos2dx,精灵加载图片之后,利用缩放改变精灵大小
- Linux操作系统下数据库服务器的关闭