libevent源码分析--evbuffer和bufferevent的关系
在libevent中还有一个很重要的部分。evbuffer和bufferevent。
evbuffer是一个缓冲区,用户可以向evbuffer添加数据,evbuffer和bufferevent经常一起使用,或者说bufferevent使用了evbuffer,bufferevent有两个evbuffer缓冲,还有event。
说明bufferevent是一个带有缓冲区的I/O。可以使用它们!用户可以通过bufferevent相关的函数往evbuffer缓冲区中添加需要发送的内同,内部机制可以保证发送。当有数据在bufferevent上的套接字上时,数据被读入到bufferevent内部的evbuffer缓冲区!
这样一来,用户程序需要交互的就是使用bufferevent相关函数想bufferevent内部的两个evbuffer(一个为读缓冲,一个为写缓冲)写数据/取数据,发送和接受都是bufferevent内部实现的。当然内部的发送和读取都是非阻塞的!!
其中evbuffer并没有显示的使用malloc在堆区申请空间,而是使用了内核为每个套接字在栈上分配的事件,在这个空间不够时,再申请空间存放数据,使用函数evbuffer_expand()函数。具体的步骤是怎么回事呢?(这里分析的是libevent-1.4.12-stable)
一、首先申请bufferevent
使用bufferevent_new函数申请一个struct bufferevent.首先是malloc了一些结构体,然后调用了两个重量级的函数,event_set,这个函数被调用两次,分别对应bufferevent中的ev_read和ev_write。这个函数是干什么的,在不久以前的某个时刻也注重分析了,就是让某一个套接字初始化给具体的event,并且初始化这个event所要关注的事件和事件处理函数,这么一来,bufferevent中的两个event被初始化了!暂且不说注册的两个函数(bufferevent_readcb bufferevent_writecb),这也是重量级的。
然后调用函数bufferevent_setcb函数,这个函数注册层的回调函数,这函数处理了从evbuffer中读取数据后的相应处理(怎么处理就是用户层的事情了)
二、调用bufferevent_enable函数
这个函数中同样调用了一个以前的重量级函数event_add(),这个函数可以理解为将某个event添加到event_base中,这样这个套接字就可以被处理,等到有数据到达就会被触发。其实到目前为止,已经可以结束了,上下的就是自己写bufferevent_setcb函数中注册的两个函数了。
整天看着两步,再对比以前使用libevent的流程,之前多一个event_init全局初始化,然后多一个event_dispatch()函数,也就是说,这个bufferevent知识多了两个evbuffer,然后对event_set函数和event_add函数进行再次封装!
三、bufferevent_readcb()
这个函数是在buffer_new函数中别event_set函数调用的,event_set也就是对传递给的event参数做相应的初始化,但是bufferevent_readcb函数的具体内容是什么呢?
咱们这里不考虑什么读/写的标准,都是默认值。在这个函数中调用了evbuffer_read函数,这个函数可以直接调用了系统调用read(),,读取的函数就是直接调用bufferevent_add函数继续关注这个event
四、bufferevent_write()函数
其实和上面的那个函数类似,调用了evbuffer_write函数,这个函数总调用了write函数,然后调用bufferevent_add函数继续关注这个事件
这是使用bufferevent的整个过程!!
其实想要知道libevent是怎么使用evbuffer,还需要知道是怎么调用的!
libevent源码分析--evbuffer和bufferevent的关系,布布扣,bubuko.com
原文:http://blog.csdn.net/yusiguyuan/article/details/20482675