事件处理

libevent的基本的操作单元就是事件。每个事件体现一组条件,包括:
1.就绪的可读或可写的文件描述符
2.变得就绪的可读或者可写的文件描述符
3.时间超时
4.发生信号
5.用户触发事件。

一、创建事件对象
#define EV_TIMEOUT      0x01   //超时则触发事件
#define EV_READ         0x02   //提供的文件描述符可读则触发事件
#define EV_WRITE        0x04   //提供的文件描述符可写则触发事件
#define EV_SIGNAL       0x08   //用于信号检测
#define EV_PERSIST      0x10   //表明事件是持久的。
#define EV_ET           0x20   //事件应该是边沿触发

typedefvoid (*event_callback_fn)(evutil_socket_t, short, void *);

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);
event_new分配并构造一个event。what参数是以上的值的集合。如果fd非负,它就是我们要监视读写事件的文件。当事件被触发,就调用回调函数cb.
出现内部错误或提供无效参数的话,函数将返回NULL。
event_free()释放一个event。
二、事件持久性
默认的,当一个未定的事件变活跃时,在回调函数被执行钱会变成非未定状态。所有如果想让事件变会未定,则需要在回调函数里调用event_add() 。如果事件设置了EV_PERSIST属性,则事件就是持久性的。即使调用了事件回调函数,事件也一直是未定的。如果想让其变成非未定状态,则需要在回调函数中调用event_del()。
三、创建回调函数自身参数的event
void *event_self_cbarg();
我们经常需要创建一个接收自身作为回调函数参数的event。你不能只给event_new传一个event指针参数,因为此时event还没生成。这时就用得上event_self_cbarg(),该函数返回一个神奇的指针,当被作为回调函数指针时,它告诉event_new()创建一个接收自身做回调参数的event。
四、超时事件
#define evtimer_new(base, callback, arg) \
    event_new((base), -1, 0, (callback), (arg))
#define evtimer_add(ev, tv) \
    event_add((ev),(tv))
#define evtimer_del(ev) \
    event_del(ev)
#define evtimer_pending(ev, tv_out) \
    event_pending((ev), EV_TIMEOUT, (tv_out))
五、信号事件
#define evsignal_new(base, signum, cb, arg) \
    event_new(base, signum, EV_SIGNAL|EV_PERSIST, cb, arg)
#define evsignal_add(ev, tv) \
    event_add((ev),(tv))
#define evsignal_del(ev) \
    event_del(ev)
#define evsignal_pending(ev, what, tv_out) \
    event_pending((ev), (what), (tv_out))
六、设置不用堆分配的事件
有的人喜欢把事件分配作为大的数据结构的一部分。这样做的好处:
1.节省了内存管理器在堆上分配小的对象的开支
2.节省了对event指针解引用的事件
3.节省了event额外的缓存的时间。
int event_assign(struct event *event, struct event_base *base,
    evutil_socket_t fd, short what,
    void (*callback)(evutil_socket_t, short, void *), void *arg);
除了event之外,该函数的所有参数都是event_new的参数。成功的时候返回0,失败返回-1;
也可以用event_assign初始化在栈上分配或静态分配的event。
警告:
不能对event_base的未定事件调用event_assign。否则将出现很难调试的错误。只能先调用event_del()再
event_assign。
#define evtimer_assign(event, base, callback, arg) \
    event_assign(event, base, -1, 0, callback, arg)
#define evsignal_assign(event, base, signum, callback, arg) \
    event_assign(event, base, signum, EV_SIGNAL|EV_PERSIST, callback, arg)
size_t event_get_struct_event_size(void);
七、事件等待和非等待
int event_add(struct event *ev, conststruct timeval *tv);
一旦创建事件,就需要调用该函数让事件变成等到,否则事件不会起作用。函数成功返回0,失败则返回-1、
int event_del(struct event *ev);
在一个已经初始化的事件上调用该函数,使得事件变成非等待和不活跃。
函数成功返回0,失败则返回-1、
int event_remove_timer(struct event *ev);
该函数用于删除事件的超时而不用删除事件的IO或者信号组件。
函数成功返回0,失败则返回-1、

八、事件优先级
当多个事件同事发生时,libevent不指定event的回调的执行顺序。我们可以指定event的优先级
int event_priority_set(struct event *event, int priority);
优先级priority为0到event_base的优先级减1之间,函数成功返回0,失败则返回-1、
九、检查事件状态
int event_pending(conststruct event *ev, short what, struct timeval *tv_out);

#define event_get_signal(ev) /* ... */                 //获取事件关联的信号
evutil_socket_t event_get_fd(conststruct event *ev);  //获取事件设置的文件描述符
struct event_base *event_get_base(conststruct event *ev); //获取设置的event_base列表
short event_get_events(conststruct event *ev);
event_callback_fn event_get_callback(conststruct event *ev);
void *event_get_callback_arg(conststruct event *ev);
int event_get_priority(conststruct event *ev);

void event_get_assignment(conststruct event *event,
        struct event_base **base_out,
        evutil_socket_t *fd_out,
        short *events_out,
        event_callback_fn *callback_out,
        void **arg_out);
有时我们需要知道一个event是否被添加,则可以调用event_pending。

十、查找当前运行的事件
struct event *event_base_get_running_event(struct event_base *base);
十一、设置一次性事件
int event_base_once(struct event_base *, evutil_socket_t, short,
  void (*)(evutil_socket_t, short, void *), void *, conststruct timeval *);
十二、手动激活事件
void event_active(struct event *ev, int what, short ncalls);
十三、优化常见超时
conststruct timeval *event_base_init_common_timeout(
    struct event_base *base, conststruct timeval *duration);
十四、通知好的事件原理内存清除
int event_initialized(conststruct event *ev);

#define evsignal_initialized(ev) event_initialized(ev)
#define evtimer_initialized(ev) event_initialized(ev)










  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值