libevent源码分析和socket程序编写示例

/*==============================================================================
* 2019 -06-30 写在最前面
* libevent 简介不多说
* 安装:
* -->libevent.org官网下载,
* 		我用的最新的2.1.10稳定版和之前的1.4.x版本还是有些区别的,
*		比如事件的内部结构体定义,循环处理,小根堆,线程安全等,
*		感觉新版本对以前的功能和安全做了完善
* -->解压tar -xvzf libevent.tar.gz
* -->进入根目录,执行./autogen.sh生成configure (可能需要安装一些软件比如aclocal等因为autogen需要)
* -->执行./configure --prefix=/home/share/install 
* -->执行make verify 
* -->执行make && make install
*==============================================================================
* 2018-10-25
* 源码目录文件说明:
* event.h - 事件宏定义接口函数声明,主要结构体event的声明
* xxx-internal.h - 内部头文件即libevent内部调用,对外不可见,以达到信息隐藏
* event.c - event整体框架代码
* epoll.c - epoll封装
* select.c - select封装
* devpoll.c - dev/poll封装
* kqueue.c - kqueue封装
* min-heap.h - 以时间作为key的小根堆结构
* signal.c - 信号处理
* evutil.h和evutil.c - 辅助功能函数,包括创建socket pair和一些事件操作函数
* log.h和log.c - 日志函数
* evbuffer.c和buffer.c - libevent对缓冲区的封装
* compat/sys下queue.h - 基本数据结构实现,包括链表,双向链表,队列等
* http和evdns - 是基于libevent实现的http服务器和异步dns查询库
*
*==============================================================================
* 事件event结构体说明://所在头文件编译安装后的根目录event.h
* struct event {
*         struct event_callback ev_evcallback;	//
*         
*         union {
*                 TAILQ_ENTRY(event) ev_next_with_common_timeout;
*                 int min_heap_idx;
*         } ev_timeout_pos;
*       evutil_socket_t ev_fd;	//绑定的文件描述符
* 
*         struct event_base *ev_base;	//事件绑定的实例
* 
*         union {
*                 
*                 struct {
*                         LIST_ENTRY (event) ev_io_next;
*                         struct timeval ev_timeout;
*                 } ev_io;
*                 
*                 struct {
*                         LIST_ENTRY (event) ev_signal_next;
*                         short ev_ncalls;
*                         
*                         short *ev_pncalls;
*                 } ev_signal;
*         } ev_;
* 
*	   //关注的事件类型EV_WRITE和EV_READ - I/O事件; EV_TIMEOUT - 定时事件; EV_SIGNAL - 信号; EV_PERSIST - 辅助选项
*		//#define EV_TIMEOUT 	0x01
*		//#define EV_READ 		0x02
*		//#define EV_WRITE 	0x04
*		//#define EV_SIGNAL 	0x08
*		//#define EV_PERSIST 	0x10
*        short ev_events;
*         short ev_res;           //记录当前激活事件的类型
*         struct timeval ev_timeout;
* };
* ==============================================================================
* 2018-11-15
* 事件处理框架 event_base	//所在头文件libevent的源码根目录event-internal.h
* 该结构包含了三种事件:I/O事件、信号事件、定时事件,其中前两种分别存储在对应的链表队列中
* 								    定时事件放在小根堆上(比较酷的处理)
* struct event_base {
*          //Function pointers and other data to describe this event_base's backend. 
*         
*		//定义了事件后端的操作比如后端的
* 		//*name, 
*		//(*init)(初始化), 
*		//(*add)(注册事件),
*		//(*del)(删除事件),
*		//(*dispatch)(事件分发),
*		//(*dealloc)(注销释放资源)
*		//,等 ,该结构体的函数实现会依赖epoll,poll,select等
*		const struct eventop *evsel;	
*         // Pointer to backend-specific data. 
*         void *evbase;	//定义了后端的数据比如添加一个事件evsel->add(evbase, ev);
* 
*         // List of changes to tell backend about at next dispatch.  Only used by the O(1) backends. 
*         struct event_changelist changelist;
* 
*         //Function pointers used to describe the backend that this event_base uses for signals 
*         const struct eventop *evsigsel;	//管理信号的操作
*         // Data to implement the common signal handelr code. 
*         struct evsig_info sig;	//信号实例
* 
*         // Number of virtual events 
*         int virtual_event_count;
*         // Maximum number of virtual events active 
*         int virtual_event_count_max;
*         // Number of total events added to this event_base 
*         int event_count;
*         // Maximum number of total events added to this event_base 
*         int event_count_max;
*         // Number of total events active in this event_base 
*         int event_count_active;
*         // Maximum number of total events active in this event_base 
*         int event_count_active_max;
* 
*         // Set if we should terminate the loop once we're done processing
*          * events. 
*         int event_gotterm;	//完成事件后可以设置该值去终止循环
*         // Set if we should terminate the loop immediately 
*         int event_break;	//设置该值可以随时终止循环
*         // Set if we should start a new instance of the loop immediately. 
*         int event_continue;	//启动一个新的循环
* 
*         // The currently running priority of events 
*         int event_running_priority;	//当前运行的事件优先级
* 
*         // Set if we're running the event_base_loop function, to prevent
*          * reentrant invocation. 
*         int running_loop;	//防止循环重入
* 
*         // Set to the number of deferred_cbs we've made 'active' in the
*          * loop.  This is a hack to prevent starvation; it would be smarter
*          * to just use event_config_set_max_dispatch_interval's max_callbacks
*          * feature 
*         int n_deferreds_queued;
* 
*         /* Active event management. 
*         // An array of nactivequeues queues for active event_callbacks (ones
*          * that have triggered, and whose callbacks need to be called).  Low
*          * priority numbers are more important, and stall higher ones.
*          
*         struct evcallback_list *activequeues;	//可理解成存放队列的数组,数组的每个节点存放着一个队列,数字越低优先级越高,该变量理解为数组,优先级标号为数组下标
*         // The length of the activequeues array 
*         int nactivequeues; //链表长度
*         // A list of event_callbacks that should become active the next time
*         // * we process events, but not this time. 
*         struct evcallback_list active_later_queue; //下次激活的事件链表,下次会处理,但本次不会
* 
*         /* common timeout logic 
* 
*         // An array of common_timeout_list* for all of the common timeout
*          * values we know. 
*         struct common_timeout_list **common_timeout_queues;
*         // The number of entries used in common_timeout_queues 
*         int n_common_timeouts;
*         // The total size of common_timeout_queues. 
*         int n_common_timeouts_allocated;
* 
*         // Mapping from file descriptors to enabled (added) events 
*         struct event_io_map io;	//注册的事件文件描述符的映射
* 
*         // Mapping from signal numbers to enabled (added) events. 
*         struct event_signal_map sigmap;
* 
*         // Priority queue of events with timeouts. 
*         struct min_heap timeheap;	//管理定时事件的小根堆,优先处理小根堆的顶节点
* 
*         // Stored timeval: used to avoid calling gettimeofday/clock_gettime
*          * too often. 
*         struct timeval tv_cache;	//时间管理
* 
*         struct evutil_monotonic_timer monotonic_timer;
* 
*         // Difference between internal time (maybe from clock_gettime) and
*          * gettimeofday. 
*         struct timeval tv_clock_diff;
*         // Second in which we last updated tv_clock_diff, in monotonic time. 
*         time_t last_updated_clock_diff;
* 
* #ifndef EVENT__DISABLE_THREAD_SUPPORT
*         /* threading support 
*         // The thread currently running the event_loop for this base 
*         unsigned long th_owner_id;
*         // A lock to prevent conflicting accesses to this event_base 
*         void *th_base_lock;
*         // A condition that gets signalled when we're done processing an
*          * event with waiters on it. 
*         void *current_event_cond;
*         // Number of threads blocking on current_event_cond. 
*         int current_event_waiters;
* #endif
*         // The event whose callback is executing right now 
*         struct event_callback *current_event;
* 
* #ifdef _WIN32
*         // IOCP support structure, if IOCP is enabled. 
*         struct event_iocp_port *iocp;
* #endif
* 
*         // Flags that this base was configured with 
*         enum event_base_config_flag flags;
* 
*         struct timeval max_dispatch_time;
*         int max_dispatch_callbacks;
*         int limit_callbacks_after_prio;
* 
*         /* Notify main thread to wake up break, etc. 
*         // True if the base already has a pending notify, and we don't need
*          * to add any more. 
*         int is_notify_pending;
*         // A socketpair used by some th_notify functions to wake up the main
*          * thread. 
*         evutil_socket_t th_notify_fd[2];
*         // An event used by some th_notify functions to wake up the main
*          * thread. 
*         struct event th_notify;
*         // A function used to wake up the main thread from another thread. 
*         int (*th_notify_fn)(struct event_base *base);
* 
*         // Saved seed for weak random number generator. Some backends use
*          * this to produce fairness among sockets. Protected by th_base_lock. 
*         struct evutil_weakrand_state weakrand_seed;
* 
*         // List of event_onces that have not yet fired. 
*         LIST_HEAD(once_event_list, event_once) once_events;
* 
* };
* ==============================================================================
* 2019-03-15
*	event接口函数:	event_add、event_del、event_base_loop
*	//在源码根目录下的event.c中有实现
*	int event_add(struct event *ev, const struct timeval *timeout)		//注册事件
* 	int
* 	event_add(struct event *ev, const struct timeval *tv)
* 	{ 
*         int res;
* 	    //#define EVUTIL_FAILURE_CHECK(cond) 0 该宏原型如此,没看出玄机!!!
*         if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) {
*                 event_warnx("%s: event has no event_base set.", __func__);
*                 return -1;                                             
*         } 
*       //神奇的do while(0) ,参考我的博文有对其讲解         
*	  //#define EVBASE_ACQUIRE_LOCK(base, lockvar) do {                         \
*       //          EVLOCK_LOCK((base)->lockvar, 0);                        \
*       //  } while (0)
*         EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);                
*         
*	//该函数有两个特殊的地方:1,需要我们有锁,2,第三个参数tv_is_absolute被设置了,则这个时间是一个绝对时间,独立的,而不是添加到现有的时间间隔上                   
*	//内部实现上将新事件在堆上预留
*	//插入注册链表(内部实现上1,检测事件是否已在激活链表,2,对三类不同的事件分别处理,I/O或signal加入注册事件链表,就绪事件加入激活链表,定时事件加入小根堆)
*	//添加定时事件
*	//更新小根堆
*         res = event_add_nolock_(ev, tv, 0);
*                        
*         EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock); 
*                        
*         return (res);      
* 	}  
*
* 删除事件	
* static int
* event_del_(struct event *ev, int blocking)
* {
*         int res;
* 
*         if (EVUTIL_FAILURE_CHECK(!ev->ev_base)) {
*                 event_warnx("%s: event has no event_base set.", __func__);
*                 return -1;
*         }
* 
*         EVBASE_ACQUIRE_LOCK(ev->ev_base, th_base_lock);
* 		//blocking必须是 EVENT_DEL_{BLOCK, NOBLOCK, AUTOBLOCK,EVEN_IF_FINALIZING} 中的一个
*		//先检测blocking
*		//检测ev是否注册
		//取出ev_base,
		//从对应的链表队列中删除
*         res = event_del_nolock_(ev, blocking);
* 
*         EVBASE_RELEASE_LOCK(ev->ev_base, th_base_lock);
* 
*         return (res);
* }
* 
* int
* event_del(struct event *ev)
* {
*         return event_del_(ev, EVENT_DEL_AUTOBLOCK);
* }
*
* 事件循环
* int
* event_loop(int flags)
* {
*         return event_base_loop(current_base, flags);
* }
* 
	主循环中执行流程:
	->检测是否有跳出条件
	->根据所有timer事件的最小超时时间来设置系统I/O的timeout,返回后激活所有就绪的timer事件
	->检测是否有激活事件,存在就poll一个事件
	->更新激活等待时间
	->将就绪的I/O插入激活链表
	->将激活的signal对应的event插入激活链表
	->将小根堆的就绪定时事件插入激活链表
	->根据优先级处理激活链表中的事件
* int
* event_base_loop(struct event_base *base, int flags) 核心函数
* {
*         const struct eventop *evsel = base->evsel;
*         struct timeval tv;
*         struct timeval *tv_p;
*         int res, done, retval = 0;
* 
*         // Grab the lock.  We will release it inside evsel.dispatch, and again
*          * as we invoke user callbacks. 
*         EVBASE_ACQUIRE_LOCK(base, th_base_lock);
* 
*         if (base->running_loop) {
*                 event_warnx("%s: reentrant invocation.  Only one event_base_loop"
*                     " can run on each event_base at once.", __func__);
*                 EVBASE_RELEASE_LOCK(base, th_base_lock);
*                 return -1;
*         }
* 
*         base->running_loop = 1;
* 
*         clear_time_cache(base);
* 
*         if (base->sig.ev_signal_added && base->sig.ev_n_signals_added)
*                 evsig_set_base_(base);
* 
*         done = 0;
* 
* #ifndef EVENT__DISABLE_THREAD_SUPPORT
*         base->th_owner_id = EVTHREAD_GET_ID();
* #endif
* 
*         base->event_gotterm = base->event_break = 0;
* 
*         while (!done) {
*                 base->event_continue = 0;
*                 base->n_deferreds_queued = 0;
* 			//外部是否存在跳出循环的条件
*                 // Terminate the loop if we have been asked to 
*                 if (base->event_gotterm) {
*				//可通过event_loopexit_cb()设置event_gotterm
*                         break;
*                 }
* 
*                 if (base->event_break) {
*				//可通过event_base_loopbreak()设置event_break
*                         break;
*                 }
* 			//取小根堆的最小超时时间
*                 tv_p = &tv;
*			//该事件是否激活,有激活事件就poll一个事件出来并处理无需等待
*                 if (!N_ACTIVE_CALLBACKS(base) && !(flags & EVLOOP_NONBLOCK)) {
*                         timeout_next(base, &tv_p);
*                 } else {
*                         
*                          * if we have active events, we just poll new events
*                          * without waiting.
*                          
*                         evutil_timerclear(&tv);
*                 }
* 			//没有事件,退出
*                 // If we have no events, we just exit 
*                 if (0==(flags&EVLOOP_NO_EXIT_ON_EMPTY) &&
*                     !event_haveevents(base) && !N_ACTIVE_CALLBACKS(base)) {
*                         event_debug(("%s: no events registered.", __func__));
*                         retval = 1;
*                         goto done;
*                 }
* 			//更新等待激活的时间
*                 event_queue_make_later_events_active(base);
* 			//清空时间缓存
*                 clear_time_cache(base);
* 			//将就绪的事件、I/O事件插入激活链表
*                 res = evsel->dispatch(base, tv_p);
* 
*                 if (res == -1) {
*                         event_debug(("%s: dispatch returned unsuccessfully.",
*                                 __func__));
*                         retval = -1;
*                         goto done;
*                 }
* 			//更新事件缓存
*                 update_time_cache(base);
* 			//检测小根堆中的事件是否就绪,将就绪事件插入激活链表并从小根堆中删除
*                 timeout_process(base);
* 			//将激活链表中的就绪事件调用其回调函数进行处理,处理规则按优先级进行,存在低优先级的得不到及时处理
*                 if (N_ACTIVE_CALLBACKS(base)) {
*                         int n = event_process_active(base);
*                         if ((flags & EVLOOP_ONCE)
*                             && N_ACTIVE_CALLBACKS(base) == 0
*                             && n != 0)
*                                 done = 1;
*                 } else if (flags & EVLOOP_NONBLOCK)
*                         done = 1;
*         }
*         event_debug(("%s: asked to terminate loop.", __func__));                                              
* done:
*         clear_time_cache(base);
*         base->running_loop = 0;
* 
*         EVBASE_RELEASE_LOCK(base, th_base_lock);
* 
*         return (retval);
* }
* ==============================================================================
* 2019-07-19
* 程序说明:	该程序定义了两个base:一个是用于socket,一个用于定时事件,socket和定时事件没区别开;
*				该程序只是用于测试,里面存在fd泄露问题未处理
*				2019-07-17 编写socket的读写事件和client进行测试[done]
*				2019-07-18 编写定时事件并测试[done]
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <pthread.h>

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sched.h>
#include <signal.h>
#include <sys/time.h>


#include "event2/event.h"
#include "event2/bufferevent.h"

/*
struct event;
*/
#include "event2/event_struct.h"

/*
定义#define evtimer_set(ev, cb, arg)    event_set((ev), -1, 0, (cb), (arg))
*/
#include "event2/event_compat.h"

static void printLog(int severity,const char *msg)
{
	printf("level[%d]:%s\n",severity,msg);	
}

static void printLog1(int severity,const char *msg, int ret)
{
	printf("level[%d]:%s,0x%x.\n",severity,msg,ret);	
}

//typedef void (*event_fatal_cb)(int err);
static void errProc(int err)
{
	printf("err[%d].\n",err);	
}

void do_read(evutil_socket_t fd, short what, void *args)
{
	unsigned char buff[1024];
	int len = 0;

	memset(buff,'\0',1024);
	len = recv(fd,buff,1024,0);
	if(len <= 0)
	{
		event_msgx("read nothing.");
		return ;
	}
	event_msgx("read[%d]:%s",len,buff);


	
}
void do_write(evutil_socket_t fd, short what, void *args)
{
	int len = 0;

	len = send(fd,args,strlen(args),0);
	if(len <= 0)
	{
		event_msgx("write err.");
		return ;
	}
	event_msgx("write[%d]:%s",len,args);
}

void event_work(struct event_base *base,
					evutil_socket_t fd,
					short what)
{
	int ret;
	//分配和构造一个新事件
	struct event *ev;
	switch(what){
		case EV_READ:
			//printf("ev_read.\n");
			ev = event_new(base,fd,what,do_read,"read event.");
			if(ev == NULL)
			{
				printf("event new err.\n");
				return ;
			}
			break;
		case EV_WRITE:			
			ev = event_new(base,fd,what,do_write,"write event.");
			break;
	}
	const struct timeval tv = {5,0};
	//printf("event add.\n");
	ret = event_add(ev,&tv);
	if(ret < 0)
	{
		printf("event add err.\n");
		return ;
	}
	//printf("event dispatch.\n");
	//事件分发,注意最开始用的event_dispatch总是段错误用错了
	ret = event_base_dispatch(base);
	//printf("register done.\n");
}

void event_base_config()
{
	int i = 0;
	struct event_config *cfg;
	struct event_base *base;
	cfg = event_config_new();
	//禁用epoll
	event_config_avoid_method(cfg,"epoll");
	base = event_base_new_with_config(cfg);

	//获取支持的方法
	const char **methods = event_get_supported_methods();
	printf("config event base support methods:\n");
	for(i = 0;methods[i] != NULL;i++)
	{	
		printf("[%d]\t%s\n",i+1,methods[i]);	
	}
	event_config_free(cfg);
	//获取当前用的方法,禁用epoll后该出使用poll
	char *mechanism = (char *)event_base_get_method(base);
	printf("used is %s\n",mechanism);
	event_base_free(base);
}

void srvInit(struct event_base *base)
{
    int  flag;
    int  pos;
    int  clifd, client_len;
    struct sockaddr_in  server_address, client_address;
    struct linger timeout;
    int  fdsock_num;
    int ret =0;

	//构造一个server
	int srvfd = socket(AF_INET,SOCK_STREAM,0);	
	server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_address.sin_port = htons(9001);

    if (bind(srvfd, (struct sockaddr*)&server_address, sizeof(server_address)) < 0)
	{
		event_err("bind err.\n");
		return ;
    }
	
	if ((listen (srvfd, SOMAXCONN)) < 0)
	{
		event_err("listen err.\n");
		return ;
	}
	
	printf("===================================\n");
	printf("start recv:\n");
	while(1)
	{
		clifd = accept (srvfd, (struct sockaddr *)&client_address, (socklen_t *)&client_len);
		printf("clifd[%d] ok.\n",clifd);
		//该处可配合线程池做高并发,下面是一个错误的示范,但仍可运行是为了调试读写事件
		event_work(base,clifd,EV_READ);
		event_work(base,clifd,EV_WRITE);
	}
}


//设置定时器
struct event ev_timer;
static void taskTimer(evutil_socket_t fd, short event, void *args)
{
	struct timeval tv = {1,0};
	//struct event_base *base = (struct event_base *)args;
	printf("time arrive.\n");
	event_add(&ev_timer,&tv);
}
int setTimer(struct event_base *base)
{
	struct timeval tv = {1,0};
	
	evtimer_set(&ev_timer,taskTimer,&ev_timer);
	event_base_set(base,&ev_timer);
	//evtimer_add(&ev_timer,&tv);
	event_add(&ev_timer,&tv);
	//事件分发,注意最开始用的event_dispatch总是段错误用错了
	event_base_dispatch(base);
}

int main()
{
        //自定义函数要写在开头,后面base在申请时会调用
        //自定义函数顺序:内存-->日志-->异常
	//注册异常时执行的函数
	event_set_fatal_callback(errProc);
	//注册新的日志打印函数
	//event_set_log_callback(printLog1);
	event_set_log_callback(printLog);
	//event_set_log_callback(NULL);
	event_msgx("test msgx log oper!");

	struct event_base *base = event_base_new();
	struct event_base *base_timer = event_base_new();
	
	//获取当前使用的方法
	char *mechanism = (char *)event_base_get_method(base);
	int i = 0;
	//获取当前支持的方法
	const char **methods = event_get_supported_methods();
	
	printf("support methods:\n");
	for(i = 0; methods[i] != NULL;i++)
	{
		printf("[%d]\t%s\n",i+1,methods[i]);	
	}
	event_msgx("test msgx log oper!");
	printf("used is %s\n",mechanism);
	//调用socket的收发事件
	printf("注册epoll.\n");
	srvInit(base);
	printf("注册定时器.\n");
	setTimer(base_timer);
	
	event_base_free(base);
	//构建复杂的event_base
	event_base_config();
	return 0;	
}
//用于测试server的client程序,比较简单,没做什么错误,异常等的处理
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdbool.h>
#include <sys/signal.h>
#include <sys/resource.h>
#include <pthread.h>

#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/types.h>
#include <sys/stat.h>

#include <errno.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
#include <sched.h>
#include <signal.h>
#include <sys/time.h>


int main(int argc,char **argv)
{
    int  flag;
    int  pos;
    int  clifd, client_len;
    struct sockaddr_in  server_address, client_address;
    struct linger timeout;
    int  fdsock_num;
    int ret =0;
	unsigned char buff[100];

	//构造一个cli
	int srvfd = socket(AF_INET,SOCK_STREAM,0);	
	server_address.sin_family = AF_INET;
    server_address.sin_addr.s_addr = inet_addr("127.0.0.1");
    server_address.sin_port = htons(9001);

	if(connect(srvfd,(struct sockaddr *)&server_address,sizeof(struct sockaddr_in))<0)   
	{   
		printf("connect err.\n");
	   return -2;
	}  

	printf("%s\n",argv[1]);
	send(srvfd,argv[1],strlen(argv[1]),0);
	memset(buff,'\0',100);
	recv(srvfd,buff,100,0);
	printf("recv:%s.\n",buff);
}

编译和执行

gcc server.c -I ../include/ -L ../lib/ -o server -levent
LD_LIBRARY_PATH=../lib/ ./server

开另一个终端:./client hello

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
luotuo44是一个GitHub上的开项目,其主要目的是分析libevent码。libevent是一个使用C语言编写的事件驱动库,可以用于开发高性能的网络服务器和客户端应用程序。 在分析libevent码时,luotuo44首先研究了libevent的基本结构和使用方法。他深入研究了libevent的事件循环机制、事件触发方式以及事件回调函数的实现原理。通过仔细阅读代码,他详细解释了libevent是如何利用系统底层的IO多路复用技术(如select、epoll等)来实现高效的事件处理。 此外,luotuo44还分析libevent的缓冲区管理和事件优先级处理机制。他对libevent的缓冲区数据结构和操作进行了详细解读,包括如何实现缓冲区的读写以及缓冲区事件的触发和处理。他还深入探讨了libevent的事件优先级机制,介绍了如何设置和管理不同优先级的事件,并解释了事件优先级对事件处理效率的影响。 除了基本功能外,luotuo44还分析libevent的线程安全性和性能优化策略。他详细讲解了libevent的线程安全机制,包括互斥锁、条件变量等,并提供了一些最佳实践指南,以确保多线程环境下的稳定性和性能。此外,他还分享了一些他自己的性能优化经验,包括使用合适的数据结构、避免频繁内存分配与释放等。 总的来说,luotuo44的libevent分析为那些想深入了解libevent内部原理和如何正确使用libevent的开发者提供了很大的帮助。通过他的分析,读者可以更好地理解libevent的工作原理,并从中学习到一些编程技巧和优化策略。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

影帝sunny

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值