event_base 介绍

  一个event_base就是一个Reactor框架。我们在调用任何Libevent的函数前,我们都是需要先申请 event_base 结构体。对于一个event_base结构来说,它会保存一系列的event事件并且以轮训的方式去关注每一个事件,去查看哪一个事件是就绪的。(事件就绪可以从unp第6章 I/O模型中有讲到)
  如果一个 event_base设置了使用lock,那么它在多线程之间访问就是安全的。虽然event_base 可以在多线程中使用,但是一个loop仅仅只能在一个线程内。如果我们想多个线程都去轮训,那么我们只能每一个线程去申请一个event_base。
  Libevent是基于Reactor模式的一个网络库,也是基于多路复用的一个网络库。所以每一个event_base都有一个对应的多路复用的method,event_base支持的所有method如下:

  • select
  • poll
  • epoll
  • kqueue
  • devpoll
  • evport
  • win32

我们可以取消(disable)指定的method通过环境变量,比如设置 EVENT_NOQUEUE 环境变量。也可以通过调用event_config_avoid_method函数来关闭相应的method。(下面有这个函数介绍)

event_base 构造

默认的event_base
 struct event_base *  event_base_new (void)

  当我们调用event_base_new函数的时候,这个函数会检测环境变量然后去申请一个相应配置的event_base返回回来。在构造的时候它选择的method是当前OS支持最快的method。大多数场景,我们都是直接调用这个函数来申请event_base的。

current_base
struct event_base *event_init(void)
下面是Libevent对event_init 的源码实现
struct event_base *event_init(void){struct event_base *base = event_base_new();if (base != NULL)current_base = base;return (base);}
申请多个 event_base的demo
threads[THREADMAX];
for( int i = 0 ; i < THREADMAX; ++i)
{threads[i].base_ = event_init();
}

  Libevent有一个全局的eventbase叫做current_base变量。每次调用event_init的时候,都会为这个全局变量申请一个新的event_base。有的时候我们可以通过这个方式去申请多个event_base如上面的代码列子。
  对于current_base变量,Libevent有一系列的操作函数,它们默认的目标都是current_base。

Current function Obsolete current-base version
event_base_priority_init() event_priority_init()
event_base_get_method() event_get_method()
个性化event_base
event_config

  它是一个黑盒(不透明)的数据结构,我们并不能直接操作它的成员,我们只能靠相应的函数来操作它

struct event_config * event_config_new(void)

  它返回一个event_config 结构体

void event_config_free(struct event_config *cfg)

  使用完 config后,我们要释放所以调用这个函数

int event_config_avoid_method (struct event_config * cfg, const char * method)

这个函数就是我们上面提到的去关闭或者禁止某个method的函数

int event_config_require_features (struct event_config * cfg , enum event_method_feature feature)
enum event_method_feature {EV_FEATURE_ET = 0x01,//需要一个支持ET模式的methodEV_FEATURE_O1 = 0x02,//需要一个支持 O(1)去操作每个event事件的methodEV_FEATURE_FDS = 0x04,//需要一个支持任意文件描述符的method(不只socket)
};
int event_config_set_flag(struct event_config *cfg, enum event_base_config_flag flag)
enum event_base_config_flag {EVENT_BASE_FLAG_NOLOCK = 0x01, //它可以提高访问event_base的速度,但是会//导致线程安全问题EVENT_BASE_FLAG_IGNORE_ENV = 0x02,//这个标志表示在选择method的时候忽略设//置的环境变量,一般很少使用,它会增加debug难度 2.0.2版本EVENT_BASE_FLAG_STARTUP_IOCP = 0x04,//仅在windows下开启IOCPEVENT_BASE_FLAG_NO_CACHE_TIME = 0x08,//默认检测当前时间的时机是当eventloop//在运行相应的回调函数前,它会去检测更新对应的callback函数的当前时间。开启这个//选项后,不将是只更新将要运行的callback的当前时间。还要去更新剩下其他所有的活//跃事件的的callback函数时间,这个选项会增加CPU利用率,谨慎使用EVENT_BASE_FLAG_EPOLL_USE_CHANGELIST = 0x10,//以 Changlist的方式使用epoll//它可以减少系统调用,但是当fd是dup复制的时候这个选项可能会造成内核BUG!!!EVENT_BASE_FLAG_PRECISE_TIMER = 0x20//让Libevent使用更精密的计时机制2.1.2
};

以上三个操作 event_config的函数都是0成功,-1失败。

int event_config_set_num_cpus_hint(struct event_config *cfg, int cpus)

  这个函数只能在windows下当使用IOCP的时候调用,调用它可以设置使用多线程的时候,尽可能分配的核数, 2.0.7版本

int event_config_set_max_dispatch_interval(struct event_config *cfg,const struct timeval *max_interval, int max_callbacks,int min_priority);

  这个函数可以反正优先级逆制,第二个参数表示过多少时间周期去再一次检测高级的event,max_callback在检测前最多调用多少次这个低优先级的callback后去检测,第三个指对应的低优先级数, 2.1.1-alpha

构造个性化event_base

struct event_base *event_base_new_with_config(const struct event_config *cfg)

  很简单就是构造event_base

释放event_base
void event_base_free(struct event_base *base)

  释放event_base

event优先级

  默认event都是一个优先级,但是Libevent运行我们设计多优先级的event事件。优先级默认是从 0 ~ n_priorities-1 ,越小优先级越高

int event_base_priority_init(struct event_base *base, int n_priorities)

   必须在任意一个event成为活跃前就调用这个函数来设置优先级,最好在刚创建event_base后就初始化优先级,n_priorities 必须小于 EVENT_MAX_PRIORITIES。
  默认注册到event_base中的event优先级都是 n_priorities / 2.

int event_priority_set(struct event *ev, int pri)

  直接设置优先级

重启event_base在fork后

  并不是所有的method在fork之后,都能保持之前的event具有持久态,如果我们想fork之后使它之前的event的持久态仍然有效,需调重启函数

int event_reinit(struct event_base *base)

代码列子

设置ET
struct event_config *cfg;
struct event_base *base;
int i;/* My program wants to use edge-triggered events if at all possible.  SoI'll try to get a base twice: Once insisting on edge-triggered IO, andonce not. */
for (i=0; i<2; ++i) {cfg = event_config_new();/* I don't like select. */event_config_avoid_method(cfg, "select");if (i == 0)event_config_require_features(cfg, EV_FEATURE_ET);base = event_base_new_with_config(cfg);event_config_free(cfg);if (base)break;/* If we get here, event_base_new_with_config() returned NULL.  Ifthis is the first time around the loop, we'll try again withoutsetting EV_FEATURE_ET.  If this is the second time around theloop, we'll give up. */
}
防止优先级反转设置
struct event_config *cfg;
struct event_base *base;cfg = event_config_new();
if (!cfg)/* Handle error */;/* I'm going to have events running at two priorities.  I expect thatsome of my priority-1 events are going to have pretty slow callbacks,so I don't want more than 100 msec to elapse (or 5 callbacks) beforechecking for priority-0 events. */
struct timeval msec_100 = { 0, 100*1000 };
event_config_set_max_dispatch_interval(cfg, &msec_100, 5, 1);base = event_base_new_with_config(cfg);
if (!base)/* Handle error */;event_base_priority_init(base, 2);
显示支持的所有method的列子

返回的一个字符串数组,最后一个是空指针

int i;
const char **methods = event_get_supported_methods();
printf("Starting Libevent %s.  Available methods are:\n",event_get_version());
for (i=0; methods[i] != NULL; ++i) {printf("    %s\n", methods[i]);
}
显示当前event_base的method和event特性
struct event_base *base;
enum event_method_feature f;
base = event_base_new();
if (!base) {puts("Couldn't get an event_base!");
} else {printf("Using Libevent with backend method %s.",event_base_get_method(base));f = event_base_get_features(base);if ((f & EV_FEATURE_ET))printf("  Edge-triggered events are supported.");if ((f & EV_FEATURE_O1))printf("  O(1) event notification is supported.");if ((f & EV_FEATURE_FDS))printf("  All FD types are supported.");puts("");
}
重启event_base
struct event_base *base = event_base_new();/* ... add some events to the event_base ... */if (fork()) {/* In parent */doSomething
} else {/* In child */event_reinit(base);doSomething
}

event_base相关推荐

  1. 【Libevent】Libevent学习笔记(二):创建event_base

    00. 目录 文章目录 00. 目录 01. 简介 02. 创建默认的event_base 03. 创建复杂的event_base 3.1 event_config_new函数 3.2 event_b ...

  2. libevent源码学习-----event_base事件循环

    event_base是libevent的事件驱动,也是Reactor模式的直接体现.任何使用libevent的代码最开始都需要创建一个base,之后的任何接口函数都和这个base关联着,下面是stru ...

  3. Libevent源码分析-----配置event_base

     出处:  http://blog.csdn.net/luotuo44/article/details/38443569 前面的博文都是讲一些Libevent的一些辅助结构,现在来讲一下关键结构体 ...

  4. 事件根基event_base、事件循环event_loop、事件event、信号事件SignalEvent

    一.event_base (一) libevent简介与浅谈event_base libevent实际上就是对底层select/poll/epoll等进行了封装,每个event_base都有一种&qu ...

  5. c/c++:Libevent应用(Libevent介绍、 事件处理框架 - event_base、事件循环、事件、带缓冲区的事件、链接监听器)

    目录 1. Libevent介绍 1.1 安装Libevent 2. 事件处理框架 - event_base 2.1 event_base API函数 event_base和fork(进程)关系: 3 ...

  6. Libevent 源码学习笔记(1)event 与 event_base

    目录 event event_base eventop evcb_closure event_callback event_changelist evsig_info event_io_map eve ...

  7. 使用libevent多线程验证Linux上的服务器惊群现象

    什么是惊群现象? 惊群(thundering herd)是指,只有一个子进程能获得连接,但所有N个子进程却都被唤醒了,这种情况将使性能受损. 举一个很简单的例子,当你往一群鸽子中间扔一块食物,虽然最终 ...

  8. libevent介绍

    libevent是一款事件驱动的网络开发包 由于采用 c 语言开发 体积小巧,跨平台,速度极快. 通常我们在建立服务器的处理模型的时候,主要是下面集中模型; (1)    a new Connecti ...

  9. linux下使用NetBeans调试libevent库

    1.安装libevent 参考:http://blog.csdn.net/unix21/article/details/8679269 libevent安装在usr/local/libevent下 2 ...

最新文章

  1. python import io_详解Python IO编程
  2. python连接sqlserver_python 链接sqlserver 写接口实例
  3. python 数据增强
  4. 线程和进程有什么区别
  5. python项目NoReverseMatch: Reverse for ‘topic‘ with arguments ‘(‘‘,)‘ not found解决方法
  6. 达观数据分析平台架构和Hive实践
  7. java union方法参数_Java Geometry.union方法代碼示例
  8. Mybatis 动态sql语句(if标签和where标签)
  9. Windows 10 Creators Update [ISO官方镜像][15063][1703][x64][x86][创意者更新正式版]
  10. 使用refs获取节点_闲庭信步聊前端 - 原来你是这样的Refs
  11. Java构造字符串算法题_LeetCode算法题-Repeated Substring Pattern(Java实现)
  12. SAP Basis常用事务代码
  13. android 编译模块
  14. Spring事件监听机制
  15. eBay SOA开源平台
  16. python中--snip--是什么意思
  17. 使用枚举实现英文转盲文
  18. io端口与ion内存
  19. 个人计算机更新主要基于,计算机基础知练识习题.doc
  20. Facebook再现丑闻,约100位应用程序开发人员偷看用户数据

热门文章

  1. Pandas中的map(), apply()和applymap()的应用
  2. 国海证券分析报告(0608)
  3. 软件工程-软件测试-测试方法
  4. boos里的AHCI RAID_纳尼?虚拟机里的vivado快30%? -- Vivado实用系列
  5. Debug Information
  6. 600+ 道 Java面试题及答案整理(2021最新版)
  7. 计算机爱好者协会招生ppt,2010年度电脑爱好者协会总结.doc
  8. php生成随机数永不重复,PHP生成不重复随机数的方法汇总
  9. ReportViewer 工具栏为英文
  10. Python并行计算加速建模,for循环等