event

12人阅读 评论(0) 收藏 举报
分类:

概念

 Libevent的基本操作单元就是event。每一个事件都代表一列情况:
1.文件描述符就绪
2.时间器就绪
3.信号就绪
4.用户事件就绪
这几个事件有相同的生命周期,一旦通过调用event_new 设置 event 并与 event_base相关联后,event 事件就会被初始化。初始化后,当我们使用这个event的时候,需要先把它注册到event_base中,通过event_add 将 该event注册为 pendding态(未决态)。
如果这个event绑定的事件就绪的话,event就会被激活。接着它的回调函数就会运行。如果没设置 persistent(持久),则执行完一次回调函数后,该event就会是 非 pendding态,也就是说该事件只会被激活一次。(活跃后调用其回调函数视为激活)
如果设置了 persistent 选项,则它会一直为pendding态,一旦再次就绪,其回调函数就会被再次调用。

修改event的pendding态
event_add  设置event为 pendding态
event_del  设置event为 non-pendding态

申请event

#define EV_TIMEOUT      0x01 
//第一次通过event_new申请event的时候会忽略EV_TIMEOUT标志,它得通过event_add 设置
#define EV_READ         0x02  //设置关注可读事件
#define EV_WRITE        0x04//设置关注可写事件
#define EV_SIGNAL       0x08  //设置关注信号事件
#define EV_PERSIST      0x10  
//设置持久,持久就是即使跑了回调函数event还是pendding的
#define EV_ET           0x20  //设置ET 为了epoll

typedef void (*event_callback_fn)(evutil_socket_t fd, short what, void * arg);

struct event *event_new(struct event_base *base, evutil_socket_t fd,
    short what, event_callback_fn cb,
    void *arg);

void event_free(struct event *event);

fd 为一个正数,what 为选项,arg 是参数。
当调用失败时返回NULL。
新的event都是 非注册过的(non-pending),我们需要通过调用event_add来注册使其成为注册过的未决态。
event_free 是安全释放 event的函数。
对于 event_new 来说,它会把它的形参中的 fd , what, arg 三个参数来传给回调函数。

Persistence

  持久化,默认event是不持久化的,默认的event调用完 回调后,event就会立即变为 non-pendding状态,不再专注事件,除非在回调函数内再次通过 event_add 注册该事件。如果我们设置了EV_PERSIST , 使 event 持久化的话,那么它一直都是pendding状态。
  如果我们设置了EV_PERSIST选项,但又不想再关注该事件,则在调用event_del删除该事件,使其状态 成为 non-pendding即可。

当持久化遇上超时

  因为我们初始化event的时候,EV_TIMEOUT 会忽略,所有得后期通过 event_add来设置。但是当持久化遇到timeout后,每次回调函数 执行完毕后,timeout就会被重置为了下一轮的超时作准备。当timeout 与 其他关心事件遇到一起后,对于event的活跃判定如下:
1. 关心的事件就绪了
2. timeout超时了

给自己回调函数如何传递event过去

void *event_self_cbarg()

  我们知道,给回调函数传参是通过 event_new 这个函数来传递的,它申请event的同时,注册回调函数,调用时给回调函数传参,但是我们无法在调event_new的时候,传递一个event自己的地址,因为那个时候event还未申请,所以通过event_self_cbarg()返回对应的一个magic 数,通过这个magic数,Libevent就知道传参的时候就把对应的event传递过去即可。

#include <event2/event.h>

static int n_calls = 0;

void cb_func(evutil_socket_t fd, short what, void *arg)
{
    struct event *me = arg;

    printf("cb_func called %d times so far.\n", ++n_calls);

    if (n_calls > 100)
       event_del(me);
}

void run(struct event_base *base)
{
    struct timeval one_sec = { 1, 0 };
    struct event *ev;
    /* We're going to set up a repeating timer to get called called 100
       times. */
    ev = event_new(base, -1, EV_PERSIST, cb_func, event_self_cbarg());
    event_add(ev, &one_sec);
    event_base_dispatch(base);
}
查看评论
    个人资料
    持之以恒
    等级:
    访问量: 2万+
    积分: 2111
    排名: 2万+
    最新评论