Libevent源码分析—event_init()
event_init()
- 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()的更多相关文章
- 【转】libevent源码分析
libevent源码分析 转自:http://www.cnblogs.com/hustcat/archive/2010/08/31/1814022.html 这两天没事,看了一下Memcached和l ...
- Libevent源码分析 (1) hello-world
Libevent源码分析 (1) hello-world ⑨月份接触了久闻大名的libevent,当时想读读源码,可是由于事情比较多一直没有时间,现在手头的东西基本告一段落了,我准备读读libeven ...
- Libevent源码分析系列【转】
转自:https://www.cnblogs.com/zxiner/p/6919021.html 1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了 ...
- Libevent源码分析系列
1.使用libevent库 源码那么多,该怎么分析从哪分析呢?一个好的方法就是先用起来,会用了,然后去看底层相应的源码,这样比较有条理,自上向下掌握.下面用libevent库写个程序,每隔1秒 ...
- libevent源码分析
这两天没事,看了一下Memcached和libevent的源码,做个小总结. 1.入门 1.1.概述Libevent是一个用于开发可扩展性网络服务器的基于事件驱动(event-driven)模型的网络 ...
- Libevent源码分析—event_base_dispatch()
我们知道libevent是一个Reactor模式的事件驱动的网络库. 到目前为止,我们已经看了核心的event和event_base结构体的源码,看了初始化这两个结构体的源码,看了注册event的 ...
- libevent源码分析二--timeout事件响应
libevent不仅支持io事件,同时还支持timeout事件与signal事件,这篇文件将分析libevent是如何组织timeout事件以及如何响应timeout事件. 1. min_heap ...
- libevent源码分析一--io事件响应
这篇文章将分析libevent如何组织io事件,如何捕捉事件的发生并进行相应的响应.这里不会详细分析event与event_base的细节,仅描述io事件如何存储与如何响应. 1. select l ...
- Libevent源码分析—event, event_base
event和event_base是libevent的两个核心结构体,分别是反应堆模式中的Event和Reactor.源码分别位于event.h和event-internal.h中 1.event: s ...
随机推荐
- ls命令的20个实用范例
contents ls -l -h -lhS -l --block-size=M -a -d */ -g -G -n --color=never -i -p -r -R -t ls ~ ls --ve ...
- 事务隔离级别与传播机制,spring+mybatis+atomikos实现分布式事务管理
1.事务的定义:事务是指多个操作单元组成的合集,多个单元操作是整体不可分割的,要么都操作不成功,要么都成功.其必须遵循四个原则(ACID). 原子性(Atomicity):即事务是不可分割的最小工作单 ...
- java多线程基本概述(三)——同步块
1.1.synchronized方法的弊端 package commonutils; public class CommonUtils { public static long beginTime1; ...
- python os模块常用方法
OS模块是Python标准库中的一个操作模块,主要用于处理Linux操作系统中的文件和目录 1.要使用OS必须先导入OS import os 2.os.getcwd()获取当前路径. print os ...
- finally块执行时间
finally块在代码中什么时候被执行? 在Java语言的异常处理中,finally块的作用十九为了保证无论出现什么情况,finally块里面的代码一定会被执行.由于程序执行return就以为这结束对 ...
- DOM0 DOM2 DOM3
DOM0 DOM2 DOM3 DOM是什么 W3C 文档对象模型 (DOM) 是中立于平台和语言的接口,它允许程序和脚本动态地访问和更新文档的内容.结构和样式. DOM 定义了访问 HTML 和 ...
- Entity Framework查询注意
首先我们看下where的方法,直接查看定义(定义如下),其实一种是对IEnumerable的扩展,一种是对IQueryable的扩展,直接看最常用的,其实区别就在IEnumerable的扩展的参数是系 ...
- Android SQLite与ListView的简单使用
2017-04-25 初写博客有很多地方都有不足,希望各位大神给点建议. 回归主题,这次简单的给大家介绍一下Android SQLite与ListView的简单使用sqlite在上节中有介绍,所以在这 ...
- python——模块
一.导入模块 Python之所以应用越来越广泛,在一定程度上也依赖于其为程序员提供了大量的模块以供使用,如果想要使用模块,则需要导入.导入模块有一下几种方法: 1 import module 2 fr ...
- 阿里云主机试用之自建站点和ftp上传所遇的2个问题
1.Access to the requested object is only available from the local network 其实我并没有自建站点,只是使用了XAMPP来建了ap ...