目录
- 4. 事件管理
- 4.1 event_new
- 4.2 event_free
- 4.3 event_debug_unassign
- 备注
- 4.4 event_add
- 4.5 event_del
- 4.6 event_base_once
- 4.7 event_pending
- 4.8 event_self_cbarg
- 4.9 event_assign
- 4.10 event_finalize
- 4.11 event_free_finalize
- 4.12 event_remove_timer
- 原型
- 4.13 event_del_noblock
- 4.14 event_del_block
- 4.15 event_active
- 4.16 event_initialized
- 4.17 event_get_fd
- 4.18 event_get_base
- 4.19 event_get_events
- 4.20 event_get_callback
- 4.21 event_get_callback_arg
- 4.22 event_get_priority
- 4.23 event_get_assignment
- 4.24 event_get_struct_event_size
- 4.25 event_base_priority_init
- 4.26 event_base_get_npriorities
- 4.27 event_priority_set
- 4.28 event_set_mem_functions
- 4.29 event_base_set
- 4.30 event_gettime_monotonic
4. 事件管理
4.1 event_new
功能
分配并初始化一个event事件,后续可以将这个event添加到event_base。
备注
多个event同时对同一个文件句柄进行监听是OK的。但是它们必须要么同时是边缘触发的类型,要么同时是水平触发类型。
原型
struct event *event_new(struct event_base *base, evutil_socket_t fd,
short events, event_callback_fn callback,
void *callback_arg);
输入参数:
- fd: 对于socket事件,则对应socket句柄,对于文件事件,则对应文件句柄。
对于signal事件,则对应signal号
对于timer事件,则设置为-1 - events:当前event事件所关联的事件类型,多个事件类型可以通过二进制位OR来传递
包括EV_READ, EV_WRITE, EV_SIGNAL, EV_PERSIST, EV_ET。其中EV_PERSIST表示event一旦被event_add以后就一直处于事件的监视状态,除非通过event_del删除。其中EV_SIGNAL表示该event事件监听的是signal信号,而不是io事件。 - callback: 事件回调函数
- callback_arg: 事件回调的上下文参数
以下是event_callback_fn的类型定义:
typedef void (*event_callback_fn)(evutil_socket_t fd,
short events, void *callback_arg);
4.2 event_free
功能
回收一个由event_new分配的event。
备注
原型
void event_free(struct event *);
4.3 event_debug_unassign
功能
启用一些相对代价比较高的正常情况下都是关闭的调试检查手段。
备注
通常,这些检查使源码能在在crash之前,通过assert来捕获错误信息。注意,本函数必须在任何
event_base 或者 event被创建之前被调用。开启了调试模式后,可以捕获以下错误:
- 添加事件的时候发现一个event被重复assign。
- 在未分配(non-assign)事件上调用任何函数。
4.4 event_add
功能:
添加一个事件到event_base事件循环中,使其进入pending状态。
备注:
event_add将event事件放入事件调度中,当通过event_assgin或者event_new设置的事件的条件满足的时候,或者当指定的超时时间到了以后,调度器将会调用对应的回调函数。
在调用本函数前,event本身必须是已经通过 event_assign或者 event_new初始化过的。
而且,只有在event不再处于pending状态下,才可以重新调用event_assign进行初始化。
如果当前event已经在之前通过event_add设置了超时,那么本次调用将会为该event设置新的超时时间(如果timeout参数不为NULL)
原型:
int event_add(struct event *ev, const struct timeval *timeout);
4.5 event_del
功能
从调度器中删除一个指定的事件。
备注
调用本函数,不光将指定的event不再处于pending状态,另外,如果有设置超时定时器,也将一并取消。
原型
int event_del(struct event *ev);
4.6 event_base_once
功能
对于一个文件句柄进行一次调度。
备注
本函数不需要我们提前预先准备一个event,而只要通过指定文件句柄,所关心的事件类型,和回调函数、超时时间等参数就可以监听该句柄上的事件,对于一次性事件,只需要一行代码,就会比较方便。
注意:在libevent 2.0以及之前的版本,如果event永远没有被触发,那么用来保持它的内部内存将永远不会被释放。在libevent 2.1,内部内存将会在event_base_free的调用中被释放掉。但是,函数中的arg参数是不会被释放的,这个是需要你自己来决定什么时候进行释放的。
原型:
int event_base_once(struct event_base *base, evutil_socket_t fd,
short events, event_callback_fn callback, void *arg,
const struct timeval *timeout);
4.7 event_pending
功能
判断一个event事件是否已经被添加到event_base中并处于pending状态了。
备注
原型
int event_pending(const struct event *ev, short events, struct timeval *tv);
输入参数:
- ev:
- events: 所要查询的事件类型
- tv: 如果tv != NULL,那么对于timeout类型的event,tv指向的timeval将返回超时的时间。
4.8 event_self_cbarg
功能
返回一个用来告诉libevent将来在回调事件回调函数的时候必须用event的指针作为其上下文参数。
备注
由于在event_new的时候,需要我们提供事件的回调函数以及回调函数的上下文参数,如果开发者需要把event本身作为回调函数的上下文参数时,event事件本身还没有被创建,所以这个时候可以通过调用event_self_cbarg生成一个占位值告诉libevent。
原型
void *event_self_cbarg(void);
4.9 event_assign
功能
准备一个新的已经分配好内存的event事件,将其与socket句柄或者signal进行绑定,并且绑定该event事件所关心的事件类型等。
备注
区别于event_new,event_assign分配一个新的event事件,而是对已经分配好的event事件进行绑定和初始化操作。
开发人员通过自己为event分配内存然后event_assign绑定并初始化event的操作,增加了编程的灵活性,但是带来了一个副作用,因为分配内存的时候我们一般通过sizeof(event)来得到event结构体所占用的内存空间大小的,但是这样会因为未来libevent库的更新导致程序不能二进制兼容,因此,libevent提供了另外一个函数event_get_struct_event_sizel来获取event结构体的真实尺寸,以便实现程序在libevent的不同版本之间能够依然保持二进制兼容。
原型
int event_assign(struct event *ev, struct event_base *base,
evutil_socket_t fd, short events,
event_callback_fn callback, void *callback_arg);
4.10 event_finalize
功能
告诉libevent在一个多线程环境中需要安全地关闭一个event事件。
备注
如果你构建event的时候用EV_FINALIZE标记来避免死锁的话,那么你需要一个方法来移除一个事件
并确保在释放事件及其回调参数时,事件绝对不会在运行其回调函数。
为了实现这个逻辑,调用一次event_finalize或者event_free_finalize,其中第一个参数设置为0,第二个参数是event事件的指针,第三个参数是回调函数(回调函数将作为事件循环的一部分而以event事件的优先级顺序被调用)。
当你完成对event_finalize或者event_free_finalized的调用以后,对这个event事件进行event_add或者event_active两个函数的操作将不再有效,并且event_del函数也将是一个空操作。当finalize回调正在进行的时候,你不能通过event_assign或者event_set尝试改变event事件的字段。一旦回调函数被调用,你应该认为event事件结构体指向的内存是未初始化状态的。
相对于event_finalize函数而言,其中event_free_finalize函数将在finalize结束后,释放event事件的内存。
finalizer回调函数不应该让event事件重新进入pending或者active状态,也就是说它不能通过event_add或者event_active函数的调用来复苏event事件。
原型
int event_finalize(unsigned, struct event *, event_finalize_callback_fn);
4.11 event_free_finalize
功能
告诉libevent在一个多线程环境中需要安全地关闭一个event事件,并且在finalize之后,释放event事件内存。
备注
参考event_finalize中的说明。
原型
int event_free_finalize(unsigned, struct event *, event_finalize_callback_fn);
4.12 event_remove_timer
功能
如果一个event在event_add的时候设置了超时,那么通过本函数可以取消超时定时器。但是不影响这个event本身的事件调度。
原型
int event_remove_timer(struct event *ev);
4.13 event_del_noblock
功能
和event_del一样,但是当待删除的事件的回调正在另外一个线程中运行的时候,不会产生阻塞,甚至该event事件的构建的时候没有用到EV_FINALIZE标记也是如此。
备注
原型
int event_del_noblock(struct event *ev);
4.14 event_del_block
功能
和event_del一样,但是当待删除的事件的回调正在另外一个线程中运行的时候,总是产生阻塞,甚至该event事件的构建的时候没有用到EV_FINALIZE标记也是如此。
备注
原型
int event_del_block(struct event *ev);
4.15 event_active
功能
手工激活一个event事件
备注
你可以对一个处于pedning或者非pending状态的event事件使用这个函数,来使这个事件进入active状态,这样子这个事件的回调函数将在事件循环中被调用。
在多线程程序中,本函数的一个常见的用法是用来从另外一个线程来唤醒正在执行event_base_loop的线程。
原型
void event_active(struct event *ev, int res, short ncalls);
4.16 event_initialized
功能
测试一个event事件结构体是否已经被初始化。
备注
这个函数仅用于区分已清零的内存块和已初始化的事件,它很容易被未初始化的内存所混淆。因此,它应该仅用于区分已初始化的事件和零值。
原型
int event_initialized(const struct event *ev);
4.17 event_get_fd
功能
获取一个event事件的文件句柄
备注
因为对于开发者来说,我们应该秉持看不到event结构体的完整定义的观念,这个是libevent本身的设计理念。如果我们包含了event2/event.h的头文件,可以看到下面的定义:
struct event
#ifdef EVENT_IN_DOXYGEN_
{/*Empty body so that doxygen will generate documentation here.*/}
#endif
;
libevent将event的所有内部定义都峰值到了内部,对于我们来说只需要知道event是一个结构体就可以了,而我们不能直接修改或者读取内部的数据,而必须通过libevent为我们提供的相关函数来进行操作。
原型
evutil_socket_t event_get_fd(const struct event *ev);
4.18 event_get_base
功能
获取一个event事件绑定的event_base指针
备注
原型
struct event_base *event_get_base(const struct event *ev);
4.19 event_get_events
功能
获取一个event事件上面实际监听的事件类型列表。
备注
注意,多个事件类型通过二进制位OR进行组合返回。
原型
short event_get_events(const struct event *ev);
4.20 event_get_callback
功能
获取一个event事件上面实际绑定的回调函数。
备注
原型
event_callback_fn event_get_callback(const struct event *ev);
4.21 event_get_callback_arg
功能
获取一个event事件上面实际绑定的回调函数的上下文参数。
备注
原型
void *event_get_callback_arg(const struct event *ev);
4.22 event_get_priority
功能
获取一个event事件的优先级值。
备注
原型
int event_get_priority(const struct event *ev);
4.23 event_get_assignment
功能
一次性提取所有在构建event的时候所设置的参数。
备注
如果希望获取某个参数,则将其设置为非NULL指针。
原型
void event_get_assignment(const struct event *event,
struct event_base **base_out,
evutil_socket_t *fd_out, short *events_out,
event_callback_fn *callback_out, void **arg_out);
4.24 event_get_struct_event_size
功能
获取event事件结构体占用的内存大小。
备注
在手工进行event事件结构的内存分配的时候使用,为了避免不同版本的libevent之间的兼容性,不要使用sizeof(struct event)来获取event事件结构的占用的内存大小。
原型
size_t event_get_struct_event_size(void);
4.25 event_base_priority_init
功能
初始化设置event_base所支持的优先级队列的数量。
备注
原型
int event_base_priority_init(struct event_base *eb, int npriorities);
4.26 event_base_get_npriorities
功能
获取当前的event_base所设定的优先级队列的数量
备注
原型
int event_base_get_npriorities(struct event_base *eb);
4.27 event_priority_set
功能
为一个event事件设定优先级值。
备注
原型
int event_priority_set(struct event *ev, int priority);
4.28 event_set_mem_functions
功能
设置libevent进行内存管理的函数
备注
通过本函数的调用,可以将libevent内部进行内存分配、回收的相关函数替换为我们自定义的管理函数。
原型
void event_set_mem_functions(void *(*malloc_fn)(size_t sz),
void *(*realloc_fn)(void *ptr, size_t sz),
void (*free_fn)(void *ptr));
4.29 event_base_set
功能
将一个事件event重新绑定到一个新的event_base。
备注
需要确保当前正在被重新绑定的event没有在active或者pending状态中。
原型
int event_base_set(struct event_base *eb, struct event *ev);
4.30 event_gettime_monotonic
功能
获取当前单调递增的时间。
备注
原型
int event_gettime_monotonic(struct event_base *base, struct timeval *tp);