[libevent源码分析] event_set

本文详细介绍了libevent库的使用方法及核心函数,包括如何设置事件、调整事件优先级以及多线程环境中event_base的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

libevent使用event来封装网络事件回调,参数、fd。。。等一些信息,函数很简单

  1. void  
  2. event_set(struct event *ev, int fd, short events,  
  3.       void (*callback)(intshortvoid *), void *arg)  
  4. {  
  5.     /* Take the current base - caller needs to set the real base later */  
  6.     ev->ev_base = current_base; //设置成默认的current_base,如果  
  7.   
  8.     ev->ev_callback = callback; //设置事件回调callback;  
  9.     ev->ev_arg = arg;           //设置参数  
  10.     ev->ev_fd = fd;             //设置句柄  
  11.     ev->ev_events = events;     //设置当前的事件  
  12.     /* 
  13.      * EV_TIMEOUT   0x01 
  14.      * EV_READ      0x02 
  15.      * EV_WRITE     0x04 
  16.      * EV_SIGNAL    0x08 
  17.      * EV_PERSIST   0x10 
  18.      */  
  19.     ev->ev_res = 0;             //记录当前激活事件的类型  
  20.     ev->ev_flags = EVLIST_INIT; //设置事件标志,用于表示当前的事件处于什么阶段  
  21.     /* 
  22.      * EVLIST_TIMEOUT   0x01     //代表event在time堆中 
  23.      * EVLIST_INSERTED  0x02     //代表event在已注册时间链表中 
  24.      * EVLIST_SIGNAL    0x04     //未见使用 
  25.      * EVLIST_ACTIVE    0x08     //代表event在激活链表中 
  26.      * EVLIST_INTERNAL  0x10     //内部使用标记 
  27.      * EVLIST_INIT      0x80     //代表event已经被初始化 
  28.      */  
  29.     ev->ev_ncalls = 0;           //代表callback被执行多少次  
  30.     ev->ev_pncalls = NULL;       //指向ev_ncallsor指向NULL  
  31.   
  32.     min_heap_elem_init(ev);      //初始化时间堆中的索引值  
  33.   
  34.     /* by default, we put new events into the middle priority */  
  35.     if(current_base)  
  36.         ev->ev_pri = current_base->nactivequeues/2;//设置事件的权限为中间权限为默认值  
  37. }  
void
event_set(struct event *ev, int fd, short events,
	  void (*callback)(int, short, void *), void *arg)
{
	/* Take the current base - caller needs to set the real base later */
	ev->ev_base = current_base; //设置成默认的current_base,如果

	ev->ev_callback = callback; //设置事件回调callback;
	ev->ev_arg = arg;           //设置参数
	ev->ev_fd = fd;             //设置句柄
	ev->ev_events = events;     //设置当前的事件
    /*
     * EV_TIMEOUT   0x01
     * EV_READ      0x02
     * EV_WRITE     0x04
     * EV_SIGNAL    0x08
     * EV_PERSIST   0x10
     */
	ev->ev_res = 0;             //记录当前激活事件的类型
	ev->ev_flags = EVLIST_INIT; //设置事件标志,用于表示当前的事件处于什么阶段
    /*
     * EVLIST_TIMEOUT   0x01     //代表event在time堆中
     * EVLIST_INSERTED  0x02     //代表event在已注册时间链表中
     * EVLIST_SIGNAL    0x04     //未见使用
     * EVLIST_ACTIVE    0x08     //代表event在激活链表中
     * EVLIST_INTERNAL  0x10     //内部使用标记
     * EVLIST_INIT      0x80     //代表event已经被初始化
     */
	ev->ev_ncalls = 0;           //代表callback被执行多少次
	ev->ev_pncalls = NULL;       //指向ev_ncallsor指向NULL

	min_heap_elem_init(ev);      //初始化时间堆中的索引值

	/* by default, we put new events into the middle priority */
	if(current_base)
		ev->ev_pri = current_base->nactivequeues/2;//设置事件的权限为中间权限为默认值
}

使用libevent在多线程中,就会存在多个event_base来进行reactor事件模型, 就需要对struct event设置所归属的event_base
调用的函数如下:

  1. int  
  2. event_base_set(struct event_base *base, struct event *ev)  
  3. {  
  4.     /* Only innocent events may be assigned to a different base */  
  5.     if (ev->ev_flags != EVLIST_INIT)//仅仅处在初始化中的事件对象才可以设置base,用于更新ev_base  
  6.         return (-1);  
  7.   
  8.     ev->ev_base = base;  
  9.     ev->ev_pri = base->nactivequeues/2;  
  10.   
  11.     return (0);  
  12. }  
int
event_base_set(struct event_base *base, struct event *ev)
{
	/* Only innocent events may be assigned to a different base */
	if (ev->ev_flags != EVLIST_INIT)//仅仅处在初始化中的事件对象才可以设置base,用于更新ev_base
		return (-1);

	ev->ev_base = base;
	ev->ev_pri = base->nactivequeues/2;

	return (0);
}

这样当每个线程都存在一个event_base的时候,那么就可以根据event所属的线程来设置当前的event_base,
如果不设置event_base而使用默认,那么会使用current_base,current_base设置成最后一个创建的event_base对象


设置事件权限,这个函数一般都是刚创建完event_base的使用,因为它使用的是current_base

  1. int  
  2. event_priority_init(int npriorities)  
  3. {  
  4.   return event_base_priority_init(current_base, npriorities);  
  5. }  
int
event_priority_init(int npriorities)
{
  return event_base_priority_init(current_base, npriorities);
}

//重新设置event_base权限,一维是最高的。。。

  1. int  
  2. event_base_priority_init(struct event_base *base, int npriorities)  
  3. {  
  4. int i;  
  5.   
  6.   
  7. if (base->event_count_active)  
  8. return (-1);  
  9.   
  10.   
  11. if (base->nactivequeues && npriorities != base->nactivequeues) {  
  12. for (i = 0; i < base->nactivequeues; ++i) {  
  13. free(base->activequeues[i]);  
  14. }  
  15. free(base->activequeues);  
  16. }  
  17.   
  18.   
  19. /* Allocate our priority queues */  
  20. base->nactivequeues = npriorities;  
  21. base->activequeues = (struct event_list **)calloc(base->nactivequeues,  
  22.    npriorities * sizeof(struct event_list *));  
  23. if (base->activequeues == NULL)  
  24. event_err(1, "%s: calloc", __func__);  
  25.   
  26.   
  27. for (i = 0; i < base->nactivequeues; ++i) {  
  28. base->activequeues[i] = malloc(sizeof(struct event_list));  
  29. if (base->activequeues[i] == NULL)  
  30. event_err(1, "%s: malloc", __func__);  
  31. TAILQ_INIT(base->activequeues[i]);  
  32. }  
  33.   
  34.   
  35. return (0);  
  36. }  
int
event_base_priority_init(struct event_base *base, int npriorities)
{
int i;


if (base->event_count_active)
return (-1);


if (base->nactivequeues && npriorities != base->nactivequeues) {
for (i = 0; i < base->nactivequeues; ++i) {
free(base->activequeues[i]);
}
free(base->activequeues);
}


/* Allocate our priority queues */
base->nactivequeues = npriorities;
base->activequeues = (struct event_list **)calloc(base->nactivequeues,
   npriorities * sizeof(struct event_list *));
if (base->activequeues == NULL)
event_err(1, "%s: calloc", __func__);


for (i = 0; i < base->nactivequeues; ++i) {
base->activequeues[i] = malloc(sizeof(struct event_list));
if (base->activequeues[i] == NULL)
event_err(1, "%s: malloc", __func__);
TAILQ_INIT(base->activequeues[i]);
}


return (0);
}

libeven 整个源码分析和sample都在我的  githup
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值