libevent代码阅读(6)——“hello-world.c”之 io复用机制

来源:互联网 发布:oracle示例数据库安装 编辑:程序博客网 时间:2024/06/06 12:59

可以看到event_base的创建的过程中,最重要的一步就是选择一个最高效的io复用机制

可供选择的io复用机制定义如下:

// Reactor初始化的时候会从这里选择最合适的io复用机制static const struct eventop *eventops[] ={// evport的实现#ifdef _EVENT_HAVE_EVENT_PORTS&evportops,#endif// Kqueue的实现#ifdef _EVENT_HAVE_WORKING_KQUEUE&kqops,#endif// epoll的实现#ifdef _EVENT_HAVE_EPOLL&epollops,#endif// /dev/poll的实现#ifdef _EVENT_HAVE_DEVPOLL&devpollops,#endif// poll的实现#ifdef _EVENT_HAVE_POLL&pollops,#endif// select的实现#ifdef _EVENT_HAVE_SELECT&selectops,#endif// windows平台的实现#ifdef WIN32&win32ops,#endifNULL};



可以看到eventops是一个eventop*类型的数组

eventopde 的定义如下:

/* * eventop结构体封装了io复用机制必要的一些操作 * 例如注册事件、等待事件等等 * 它为event_base支持的所有后端io复用机制提供了一个统一的接口 */struct eventop {/** The name of this backend. */// 后端io复用技术的名称const char *name;/** Function to set up an event_base to use this backend.  It should * create a new structure holding whatever information is needed to * run the backend, and return it.  The returned pointer will get * stored by event_init into the event_base.evbase field.  On failure, * this function should return NULL. */// 初始化函数void *(*init)(struct event_base *);/** Enable reading/writing on a given fd or signal.  'events' will be * the events that we're trying to enable: one or more of EV_READ, * EV_WRITE, EV_SIGNAL, and EV_ET.  'old' will be those events that * were enabled on this fd previously.  'fdinfo' will be a structure * associated with the fd by the evmap; its size is defined by the * fdinfo field below.  It will be set to 0 the first time the fd is * added.  The function should return 0 on success and -1 on error. */// 注册事件int (*add)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);/** As "add", except 'events' contains the events we mean to disable. */// 删除事件int (*del)(struct event_base *, evutil_socket_t fd, short old, short events, void *fdinfo);/** Function to implement the core of an event loop.  It must see which    added events are ready, and cause event_active to be called for each    active event (usually via event_io_active or such).  It should    return 0 on success and -1 on error. */// 等待事件(即循环等待)int (*dispatch)(struct event_base *, struct timeval *);/** Function to clean up and free our data from the event_base. */// 是否io复用机制所使用的资源void (*dealloc)(struct event_base *);/** Flag: set if we need to reinitialize the event base after we fork. */// 程序调用fork之后是否需要重新初始化event_baseint need_reinit;/** Bit-array of supported event_method_features that this backend can * provide. *//* * io复用技术支持的一些特性,下面有三个可选值: * EV_FEATURE_ET = 0x01,支持边沿触发事件 * EV_FEATURE_O1 = 0x02,事件检查算法的复杂度是0(1) * EV_FEATURE_FDS = 0x04不仅能监听socket上的事件,还能监听其他类型的文件描述符上的事件 */enum event_method_feature features;/** Length of the extra information we should record for each fd that    has one or more active events.  This information is recorded    as part of the evmap entry for each fd, and passed as an argument    to the add and del functions above. *//* * 有的io复用机制需要为每个io事件队列和信号事件队列分配额外的内存 * 一避免同一个文件描述符被重复插入io复用机制的事件表中 * 下面这个字段指定了这段内存的长度 */size_t fdinfo_len;};



可以看到eventop封装了io复用机制的信息和操作,每一种io复用机制都有各自不同的操作和信息,以epollops为例:

// io复用机制——epollconst struct eventop epollops = {// 名字"epoll",// 初始化epoll_init,// 添加事件epoll_nochangelist_add,// 删除事件epoll_nochangelist_del,// 进入事件多路分发器循环epoll_dispatch,// 内存释放epoll_dealloc,// 是否需要重新初始化1, /* need reinit */// 一些特征EV_FEATURE_ET|EV_FEATURE_O1,// 额外分配的内存长度0};


1 0
原创粉丝点击