相关文章推荐
温柔的牛肉面  ·  Caused by: ...·  7 月前    · 
强健的领带  ·  Java & PHP & ...·  1 年前    · 
爱健身的木瓜  ·  Google Cloud Message ...·  1 年前    · 
Allocates a new event configuration object. The event configuration object can be used to change the behavior of an event base. @return an event_config object that can be used to store configuration, or NULL if an error is encountered. @see event_base_new_with_config(), event_config_free(), event_config // 分配新的event_config对象。event_config对象用来改变event_base的行为。 // 返回event_config对象,里面存放着配置信息,失败则返回NULL // 相关查看event_base_new_with_config,event_config_free,event_config结构体等 struct event_config * event_config_new(void) // 使用内部分配api mm_calloc分配event_config对象,并赋初值1 struct event_config *cfg = mm_calloc(1, sizeof(*cfg)); if (cfg == NULL) return (NULL); // 初始化屏蔽的后台方法列表 TAILQ_INIT(&cfg->entries); // 设置最大调度时间间隔,初始为非法值 cfg->max_dispatch_interval.tv_sec = -1; // 设置最大调度回调函数个数,初始值为int的最大值 cfg->max_dispatch_callbacks = INT_MAX; // 设置优先级后的回调函数的限制,初始值为1 cfg->limit_callbacks_after_prio = 1; // 由于初始分配时赋初值为1,经过上述显式设置之后,还有几个字段的初始值是1 // 查看event_config定义发现,还有三个字段使用的初始赋值: // n_cpus_hint = 1 // require_features = 1,查看后台方法特征宏定义,发现是边沿触发方式 // flags = 1,查看event_base支持的模式,发现是非阻塞模式 return (cfg); Deallocates all memory associated with an event configuration object @param cfg the event configuration object to be freed. // 释放event_config对象的所有内存,和event_config_new配对使用 event_config_free(struct event_config *cfg) struct event_config_entry *entry; // 遍历屏蔽的后台方法列表,释放屏蔽的后台方法项目 while ((entry = TAILQ_FIRST(&cfg->entries)) != NULL) { TAILQ_REMOVE(&cfg->entries, entry, next); event_config_entry_free(entry); // mm_calloc的释放程序 mm_free(cfg); 屏蔽的后台方法释放 // 使用内置的mm_free释放mm_calloc申请的空间 static void event_config_entry_free(struct event_config_entry *entry) if (entry->avoid_method != NULL) mm_free((char *)entry->avoid_method); mm_free(entry); * Sets one or more flags to configure what parts of the eventual event_base * will be initialized, and how they'll work. * @see event_base_config_flags, event_base_new_with_config() // 设置event_base的工作模式,需要在申请event_config之后运行,在配置event_base之前执行; // 可以设置多个工作模式同时存在,但是需要注意的是不是每种工作模式都是可以设置的, // 需要查看本地内核环境以及后台方法是否支持 event_config_set_flag(struct event_config *cfg, int flag) if (!cfg) return -1; cfg->flags |= flag; return 0;

2、设置后台方法的工作方式

Enters a required event method feature that the application demands. Note that not every feature or combination of features is supported on every platform. Code that requests features should be prepared to handle the case where event_base_new_with_config() returns NULL, as in: event_config_require_features(cfg, EV_FEATURE_ET); base = event_base_new_with_config(cfg); if (base == NULL) { // We can't get edge-triggered behavior here. event_config_require_features(cfg, 0); base = event_base_new_with_config(cfg); @param cfg the event configuration object @param feature a bitfield of one or more event_method_feature values. Replaces values from previous calls to this function. @return 0 on success, -1 on failure. @see event_method_feature, event_base_new_with_config() // 设置后台方法特征,注意不是每个平台都会支持所有特征或者支持几个特征同时存在; // 设置后台方法特征的代码应该在event_base_new_with_config之前进行; // 注意,这里不是采用或的方式,而是直接替换为输入的方法特征 event_config_require_features(struct event_config *cfg, int features) if (!cfg) return (-1); cfg->require_features = features; return (0);

3、屏蔽某些后台方法

可以通过编译选项进行屏蔽,也可以通过以下api进行手动设置
   Enters an event method that should be avoided into the configuration.
   This can be used to avoid event mechanisms that do not support certain
   file descriptor types, or for debugging to avoid certain event
   mechanisms.  An application can make use of multiple event bases to
   accommodate incompatible file descriptor types.
   @param cfg the event configuration object
   @param method the name of the event method to avoid
   @return 0 on success, -1 on failure.
// 输入需要屏蔽的方法名字;可以用来避免某些不支持特定文件描述符类型的后台方法,
// 或者调试用来屏蔽某些特定事件的机制。应用可以使用多个event_bases以适应不兼容的
// 文件描述符类型。
event_config_avoid_method(struct event_config *cfg, const char *method)
     // 申请存储屏蔽后台方法名字的空间
    struct event_config_entry *entry = mm_malloc(sizeof(*entry));
    if (entry == NULL)
        return (-1);
     // 申请后台方法名字空间
    if ((entry->avoid_method = mm_strdup(method)) == NULL) {
        mm_free(entry);
        return (-1);
     // 将屏蔽的方法插入屏蔽队列
    TAILQ_INSERT_TAIL(&cfg->entries, entry, next);
    return (0);

4、设置cpu个数提示信息

* Records a hint for the number of CPUs in the system. This is used for * tuning thread pools, etc, for optimal performance. In Libevent 2.0, * it is only on Windows, and only when IOCP is in use. * @param cfg the event configuration object * @param cpus the number of cpus * @return 0 on success, -1 on failure. // 记录有关系统cpu个数的提示;用来调整线程池;在2.0中,只能用于windows, // 而且只能当使用IOCP时才有效 event_config_set_num_cpus_hint(struct event_config *cfg, int cpus) if (!cfg) return (-1); cfg->n_cpus_hint = cpus; return (0); * Record an interval and/or a number of callbacks after which the event base * should check for new events. By default, the event base will run as many * events are as activated at the higest activated priority before checking * for new events. If you configure it by setting max_interval, it will check * the time after each callback, and not allow more than max_interval to * elapse before checking for new events. If you configure it by setting * max_callbacks to a value >= 0, it will run no more than max_callbacks * callbacks before checking for new events. * This option can decrease the latency of high-priority events, and * avoid priority inversions where multiple low-priority events keep us from * polling for high-priority events, but at the expense of slightly decreasing * the throughput. Use it with caution! * @param cfg The event_base configuration object. * @param max_interval An interval after which Libevent should stop running * callbacks and check for more events, or NULL if there should be * no such interval. * @param max_callbacks A number of callbacks after which Libevent should * stop running callbacks and check for more events, or -1 if there * should be no such limit. * @param min_priority A priority below which max_interval and max_callbacks * should not be enforced. If this is set to 0, they are enforced * for events of every priority; if it's set to 1, they're enforced * for events of priority 1 and above, and so on. * @return 0 on success, -1 on failure. // 记录event_base用于检查新事件的时间间隔或者回调函数个数;默认情况下, // event_base在检查新事件之前,应当是有多少最高优先级的激活事件就执行多少这样激活的事件; // 如果你通过max_interval设置了两次检查之间的时间间隔,它将在每次执行回调之后检查距离上一次检查新事件的 // 时间间隔是否超过了max_interval,在两次检查新事件之间不允许超过max_interval。 // 如果你通过配置max_callbacks>=0,则两次检查新事件之间不会执行超过max_callbacks个 // 回调函数。 // 这个选项可以降低高优先级事件的延迟,同时避免优先级颠倒执行,即多个低优先级事件 // 屏蔽了高优先级事件,即多个低优先级先发生,高优先级事件后发生,而event_base一直在执行低优先级事件, // 而导致高优先级事件迟迟得不到执行,但是会轻微降低吞吐量,谨慎使用这个。 // cfg: event_config对象 // max_interval:event_base停止执行回调并检查新事件的时间间隔,如果不想设置这样的间隔,可以设置为NULL // max_callbacks:event_base停止执行回调并检查新事件的已执行的最大回调函数个数,如果不需要,可以设置为-1 // min_priority:即低于这个值的优先级,就不应该强制执行max_interval和max_callbacks检查;如果设置为0, // 则对每个优先级都执行这两个检查;如果设置为1,只有priority>=1时,才执行这样的检查 event_config_set_max_dispatch_interval(struct event_config *cfg, const struct timeval *max_interval, int max_callbacks, int min_priority) // 如果max_interval不为空,则将输入的参数拷贝到cfg中, // 否则设置为非法值 if (max_interval) memcpy(&cfg->max_dispatch_interval, max_interval, sizeof(struct timeval)); cfg->max_dispatch_interval.tv_sec = -1; // 如果max_callbacks >=0,则设置为max_callbacks,否则设置为INT_MAX cfg->max_dispatch_callbacks = max_callbacks >= 0 ? max_callbacks : INT_MAX; // 如果<0,则所有优先级都执行检查,否则设置为传入参数 if (min_priority < 0) min_priority = 0; cfg->limit_callbacks_after_prio = min_priority; return (0); Get the kernel event notification mechanism used by Libevent. @param eb the event_base structure returned by event_base_new() @return a string identifying the kernel event mechanism (kqueue, epoll, etc.) // 获取event使用的内核事件通知机制。 // base是使用event_base_new()创建的event_base句柄 const char * event_base_get_method(const struct event_base *base) EVUTIL_ASSERT(base); return (base->evsel->name); Gets all event notification mechanisms supported by Libevent. This functions returns the event mechanism in order preferred by Libevent. Note that this list will include all backends that Libevent has compiled-in support for, and will not necessarily check your OS to see whether it has the required resources. @return an array with pointers to the names of support methods. The end of the array is indicated by a NULL pointer. If an error is encountered NULL is returned. // 获取event_base支持的所有事件通知机制。这个函数返回libevent选择的 // 事件机制。注意,这个列表包含libevent编译时就支持的所有后台方法, // 它不会做有关OS的必要性检查,以查看是否有必要的资源。 // 返回指针数组,每个指针指向支持方法的名字。数组的末尾指向NULL。 const char ** event_get_supported_methods(void) static const char **methods = NULL; const struct eventop **method; const char **tmp; int i = 0, k; /* count all methods */ // 遍历静态全局数组eventops,获得编译后的后台方法个数 for (method = &eventops[0]; *method != NULL; ++method) { /* allocate one more than we need for the NULL pointer */ // 分配临时空间,二级指针,用来存放名字指针 tmp = mm_calloc((i + 1), sizeof(char *)); if (tmp == NULL) return (NULL); /* populate the array with the supported methods */ // 在tmp数组中保存名字指针 for (k = 0, i = 0; eventops[k] != NULL; ++k) { tmp[i++] = eventops[k]->name; tmp[i] = NULL; if (methods != NULL) mm_free((char**)methods); methods = tmp; return (methods); Return a bitmask of the features implemented by an event base. This will be a bitwise OR of one or more of the values of event_method_feature @see event_method_feature // 返回event_base后台方法的特征。可以是多个特征通过OR方法求并的结果 event_base_get_features(const struct event_base *base) return base->evsel->features;

4、获取event_base的优先级个数

Get the number of different event priorities. @param eb the event_base structure returned by event_base_new() @return Number of different event priorities @see event_base_priority_init() // 获取不同事件优先级个数 event_base_get_npriorities(struct event_base *base) int n; if (base == NULL) base = current_base; EVBASE_ACQUIRE_LOCK(base, th_base_lock); n = base->nactivequeues; EVBASE_RELEASE_LOCK(base, th_base_lock); return (n); 由于工作上需要使用libevent-2.1.11-stable静态库,想在网上下载libevent-2.1.11-stable静态库,但是基本要C币,无奈自己本地编译了一下。 本地环境:Windows平台+VS2019 资源包括了:libevent-2.1.11-stable源码+静态库 LibeventLibevent概述Libevent使用模型Libevent库使用示例Libevent事件类型和框架结构 Libevent概述 Libevent是开源社区的一款高性能的I/O框架库,使用Libevent的著名案例有:高性能的分布式内存对象缓存软件memcached,Googlo浏览器Chromium的Linux版本。作为一个I/O框架库 1、libevent介绍 Libevent 是一个用C语言编写的、轻量级的开源高性能事件通知库,主要有以下几个亮点:事件驱动( event-driven),高性能;轻量级,专注于网络,不如 ACE 那么臃肿庞大;源代码相当精炼、易读;跨平台,支持 Windows、 Linux、 *BSD 和 Mac Os;支持多种 I/O 多路复用技术, epoll、 poll、 dev/poll、 select 和 kqueue 等;支持 I/O,定时器和信号等事件;注册事件优先级。Libevent 已经被广泛的应用,. Libevent是一个用C语言编写的基于事件触发的开源高性能网络库。著名的分布式缓存软件memecached也是基于libevent,适用于windows,linux,ios等多种平台。大量用到回调函数函数指针)的方法。于此类似的有ACE,ASIO。优点: 1.libevent是一个事件触发的网络库。专注与网络 2.跨平台。 3.使用select,dev/poll(Solaris), 最近在做Redis中间件,目标实现集群管理、分布式数据处理、高性能。由于在某些情况下,单个节点的Redis性能可能无法满足需求,并且单个机器的内存大小是受限制的。如果采用中间件的方式管理多个Redis实例,不仅可以避免单点机器内存不够用的情况,也能使性能得到大幅提升。经过Redis... Libevent介绍 libevent是一个事件触发的网络库,适用于windows、linux、bsd等多种平台,内部使用select、epoll、kqueue等系统调用管理事件机制。著名分布式缓存软件memcached也是libevent based,而且libevent在使用上可以做到跨平台,而且根据libevent官方网站上公布的数据统计,似乎也有着非凡的性能。 项目中要用到libevent,所以就自学了libevent,参考资料为张亮的《libevent源码深度剖析》和《linux高性能服务器编程》Libevent简介Libevent是开源社区一款高性能的I/O框架库,其具有如下特点:1.跨平台支持。Libevent支持Linux、UNIX和Windows。2.统一事件源。libevent对i/o事件、信号和定时事件提供统一的处理。3.线程安全。libe... libevent是一个事件通知的库。 The libevent API provides a mechanism to execute a callback function when a specific event occurs on a file descriptor or after a timeout has been reached. Furthermore, libevent also support callbacks due to signals or regula 本文转载于此 基本的socket变成是阻塞/同步的,每个操作除非已经完成,出错,或者超时才会返回,这样对于每一个请求,要使用一个线程或者单独的进程去处理,系统资源没有办法支撑大量的请求。posix定义了可以使用异步的select系统调用,但是因为它采用了轮询的方式来判断某个fd是否变成active,效率不高。于是各系统就分别提出了基于异步的系统调用,例如Linux的epoll,由于在内核层面做了支持,所以可以用O(1)的效率查找到active的fd。基本上,libevent就是对这些高效IO的封装 Libevent是一个I/O框架库,具有如下特点:跨平台支持。统一事件源,Libevent对I/O事件,信号和定时事件提供统一的处理线程安全。Libevent使用libevent_pthreads库来提供线程安全支持。基于Reactor模式实现(即主线程负责事件的产生,其余线程负责对事件的处理) 1.下载并解压libevent库 这里下载的是libevent 2.0.21 stable版本的,使用wget命令如下所示:(下载地址可通过http://libevent.org/对应的libevent版本右键复制链接获取) wget https://github.com/downloads/libevent/lib 一、libevent库的安装 Libevent 使用源码安装的方式,源码下载地址:http://libevent.org/ 下载下来后,将 Libevent 的压缩包拷贝到 Linux 系统中,然后按照以下步骤执行: 打开终端,并且进入到 Libevent 所在位置 利用 tar 命令解压 Libevent 压缩包 进入到解压开的目录中 切换到 root 模式下执行命令: ./configuer --prefix=/usr 使用 make 命令完成编译 使用 make install 命令完成安装 event_config_new 配置文件配置event_base_config_flag和event_config_set_flag 先看event_base_config_flag 按优先顺序排列的后端数组 static const struct eventop *eventops[] = { #ifdef EVENT__HAVE_EVENT_PORTS &evportops, #endif #ifdef EVENT__HAVE_WORKING_KQUEUE &kqops,