下面开始看初始化event_base结构的相关函数。相关源码位于event.c

event_init()

首先调用event_init()初始化event_base结构体
struct event_base *
event_init(void)
{
struct event_base *base = event_base_new(); //event_init()调用event_base_new()
if (base != NULL)
current_base = base;
return (base);
}

我们发现event_init()工作量很少,只是调用event_base_new()函数,所以真正初始化event_base的工作是在event_base_new()函数内完成。

event_base_new()

struct event_base *
event_base_new(void) //初始化libevent的event_base
{
int i;
struct event_base *base;
if ((base = calloc(, sizeof(struct event_base))) == NULL) //在堆上分配内存存储event_base,所有字段初始化为0
event_err(, "%s: calloc", __func__);
event_sigcb = NULL;
event_gotsig = ;
detect_monotonic(); //设置use_monotonic变量
gettime(base, &base->event_tv); //base->tv_cache.tv_sec非0,则赋给base->event_tv min_heap_ctor(&base->timeheap); //初始化定时事件的小根堆base->timeheap min_heap.h
TAILQ_INIT(&base->eventqueue); //初始化注册事件链表base->eventqueue sys/queue.h
base->sig.ev_signal_pair[] = -; //初始化信号base->sig
base->sig.ev_signal_pair[] = -; base->evbase = NULL; //初始化I/O多路复用 base->evbase
//遍历全局数组eventops[],初始化libevent的I/O多路复用机制
for (i = ; eventops[i] && !base->evbase; i++) { //以NULL标志数组结尾,只选取一个I/O多路复用机制
base->evsel = eventops[i]; //初始化base->evsel
base->evbase = base->evsel->init(base); //初始化base->evbase
}
if (base->evbase == NULL) //没有I/O多路复用
event_errx(, "%s: no event mechanism available", __func__);
if (evutil_getenv("EVENT_SHOW_METHOD")) //调用getenv()获取环境变量EVENT_SHOW_METHOD evutil.c
event_msgx("libevent using: %s\n",
base->evsel->name);
/* allocate a single active event queue */
//event_base_new()内调用event_base_priority_init()
event_base_priority_init(base, ); //设置优先级base->nactivequeues;分配数组base->activequeues。数组大小和优先级相同
return (base);
}

其中由3点需要注意:

1.该函数调用calloc()在堆上分配内存来存储event_base;

2.使用全局数组eventops[]存储系统支持的I/O多路复用机制,然后遍历该数组,选取第1个I/O多路复用机制。

3.libevent支持event有优先级,所以又调用了event_base_priority_init()来完成优先级相关的设置。

event_base_priority_init()

//设置不同event的优先级,值越小,优先级越高
//返回值:0,成功;-1,出错
int
event_base_priority_init(struct event_base *base, int npriorities)
{
int i;
if (base->event_count_active) //当前base上有活跃的events则不能设置优先级,返回。
return (-);
if (npriorities == base->nactivequeues) //设置的优先级和当前优先级相同,则直接返回
return ();
if (base->nactivequeues) { //不同,则先释放原先的activequeues数组
for (i = ; i < base->nactivequeues; ++i) {
free(base->activequeues[i]);
}
free(base->activequeues);
}
/* Allocate our priority queues */
base->nactivequeues = npriorities; //设置新的优先级
base->activequeues = (struct event_list **)
calloc(base->nactivequeues, sizeof(struct event_list *)); //设置和优先级值相同大小的event_list数组
if (base->activequeues == NULL)
event_err(, "%s: calloc", __func__);
for (i = ; i < base->nactivequeues; ++i) {
base->activequeues[i] = malloc(sizeof(struct event_list)); //初始化activequeues数组中每个元素
if (base->activequeues[i] == NULL)
event_err(, "%s: malloc", __func__);
TAILQ_INIT(base->activequeues[i]);
}
return ();
}

该函数设置优先级,初始化了event_base的nactivequeues成员和activequeues成员。优先级值越小,优先级越高。在活跃事件链表中,优先级高的event先被处理。

Libevent源码分析—event_init()的更多相关文章

  1. 【转】libevent源码分析

    libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...

  2. Libevent源码分析 (1) hello-world

    Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...

  3. Libevent源码分析系列【转】

    转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了 ...

  4. Libevent源码分析系列

    1.使用libevent库     源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒 ...

  5. libevent源码分析

    这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...

  6. Libevent源码分析—event_base_dispatch()

    我们知道libevent是一个Reactor模式的事件驱动的网络库.   到目前为止,我们已经看了核心的event和event_base结构体的源码,看了初始化这两个结构体的源码,看了注册event的 ...

  7. libevent源码分析二--timeout事件响应

    libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1.  min_heap ...

  8. libevent源码分析一--io事件响应

    这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1.  select l ...

  9. Libevent源码分析—event, event_base

    event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...

随机推荐

  1. [转载]转载一篇好文章作为Java与面向对象之随感(3)

    关于对象与引用之间的一些基本概念. 初学Java时,在很长一段时间里,总觉得基本概念很模糊.后来才知道,在许多Java书中,把对象和对象的引用混为一谈.可是,如果我分不清对象与对象引用, 那实在没法很 ...

  2. UPS不间断电源网络功能介绍

    UPS不间断电源网络功能介绍 随着联网技术的善及,用户又向UPS提出了更高的要求:ups电源应具有无人値守的功铅酸蓄电池能,不但具有自检的功能,还应具有联网功能,在网上UPS不间断电源可以随时观察up ...

  3. stm32之USART学习

    首先,我是看着这位博主的文章受到的启发,进而加深了自己对USART的理解.下面是自己改装并实验过的程序. 原文:http://www.cnblogs.com/greatwgb/archive/2011 ...

  4. dotnetcore中的IOptionsSnapshot<>的自动更新原理

    1.首先讲讲ChangeToken.OnChange方法: 原理是给一个CancellationToken注册一个消费者委托,调用CancellationToken的Cancel的时候会调用这个Can ...

  5. JavaScript异步编程

    前言 如果你有志于成为一个优秀的前端工程师,或是想要深入学习JavaScript,异步编程是必不可少的一个知识点,这也是区分初级,中级或高级前端的依据之一.如果你对异步编程没有太清晰的概念,那么我建议 ...

  6. 常用js功能函数汇总(持续更新ing)

    ////////////////////获取元素属性/////////////////// function getStyle(obj,name) { if(obj.currentStyle) { r ...

  7. R语言面向对象编程:S3和R6

    一.基于S3的面向对象编程 基于S3的面向对象编程是一种基于泛型函数(generic function)的实现方式. 1.S3函数的创建 S3对象组成:generic(generic FUN)+met ...

  8. hdu698 Just a Hook 线段树-成段更新

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1698 很简单的一个线段树的题目,每次更新采用lazy思想,这里我采用了增加一个变量z,z不等于0时其绝 ...

  9. hdu2594 Simpsons’ Hidden Talents

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2594 思路: 其实就是求相同的最长前缀与最长后缀 KMP算法的简单应用: 假设输入的两个字符串分别是s ...

  10. [刷题]算法竞赛入门经典(第2版) 4-8/UVa12108 - Extraordinarily Tired Students

    书上具体所有题目:http://pan.baidu.com/s/1hssH0KO 代码:(Accepted,0 ms) //UVa12108 - Extraordinarily Tired Stude ...