event

概念

 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);
}
阅读更多
个人分类: Libevent
上一篇EventLoop
下一篇用c++流读取文件
想对作者说点什么? 我来说一句

eventlog日志设计文档

2009年01月19日 584KB 下载

javascript中event详解

2010年05月15日 5KB 下载

c++ thread event

2010年11月25日 510B 下载

spring event

2009年04月07日 12KB 下载

OSGI服务 DS EVENT

2010年02月21日 185KB 下载

android事件分发Demo

2016年01月11日 3.16MB 下载

60个PowerBuilder数据窗口技巧

2010年09月06日 52KB 下载

MSAJaxEvents

2013年09月09日 102KB 下载

没有更多推荐了,返回首页

关闭
关闭