Redis的事件管理和定时器的管理都是自己来实现的,Redis的事件管理分为两部分,一部分是封装了系统的异步事件API,还有一部分是在这基础上封装了一个通用的事件管理器,根据具体的系统来决定具体使用哪个异步管理API。

先来说说Redis支持哪些异步的系统API。Redis内部封装了epoll,evport,kqueue,select这四个原始的事件管理器。

那epoll举个例子解析一下吧。

 typedef struct aeApiState
{
int epfd; //文件描述符
struct epoll_event *events;//epoll实例
} aeApiState;

这个结构体封装了一个具体的事件实例。

封装的接口函数:

 static int aeApiCreate(aeEventLoop *eventLoop) //创建一个事件管理器
static int aeApiResize(aeEventLoop *eventLoop, int setsize) //重置事件管理器管理事件的个数
static void aeApiFree(aeEventLoop *eventLoop) //删除一个事件管理器
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)//向事件管理器中添加一个事件
static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int delmask) //从时间管理器中删除一个事件
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)//激活事件管理器,返回已经触发的事件的个数
static char *aeApiName(void) //获取当前使用的是什么事件模型
1 static int aeApiCreate(aeEventLoop *eventLoop) //创建一个事件管理器
 /*创建成功返回0,否则返回-1*/
static int aeApiCreate(aeEventLoop *eventLoop)
{
aeApiState *state = zmalloc(sizeof(aeApiState)); if (!state) return -;
/*直接按size申请内存*/
state->events = zmalloc(sizeof(struct epoll_event) * eventLoop->setsize);
/*事件内存失败时要释放结构体的内存,防止出现内存泄露*/
if (!state->events)
{
zfree(state);
return -;
}
/*创建epoll描述符,如果创建失败,记得把上面申请的内存释放掉*/
state->epfd = epoll_create(); /* 1024 is just a hint for the kernel */
if (state->epfd == -)
{
zfree(state->events);
zfree(state);
return -;
}
eventLoop->apidata = state;
return ;
}
2 static int aeApiResize(aeEventLoop *eventLoop, int setsize) //重置事件管理器管理事件的个数
/*重置可接受事件的个数,这个函数不能直接调用,因为没有检查新size和旧size的大小关系,如果小了,直接重置会出问题*/
static int aeApiResize(aeEventLoop *eventLoop, int setsize)
{
aeApiState *state = eventLoop->apidata; state->events = zrealloc(state->events, sizeof(struct epoll_event)*setsize);
return ;
}
4 static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)//向事件管理器中添加一个事件
 /*向epoll中增加事件,需要注册新的文件描述符和需要监控的事件类型*/
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask)
{
aeApiState *state = eventLoop->apidata;
struct epoll_event ee;
/*因为epoll的维护是用数组维护的,通过下标的方式可以直接访问,省时省力。如果这个节点已经激活了,那新事件添加就好了*/
int op = eventLoop->events[fd].mask == AE_NONE ? EPOLL_CTL_ADD : EPOLL_CTL_MOD; ee.events = ;
mask |= eventLoop->events[fd].mask; /* Merge old events */
if (mask & AE_READABLE) ee.events |= EPOLLIN;
if (mask & AE_WRITABLE) ee.events |= EPOLLOUT;
ee.data.u64 = ; /* avoid valgrind warning */
ee.data.fd = fd;
if (epoll_ctl(state->epfd,op,fd,&ee) == -) return -;
return ;
}
6 static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)//激活事件管理器,返回已经触发的事件的个数
/*获取事件队列*/
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp)
{
aeApiState *state = eventLoop->apidata;
int retval, numevents = ; retval = epoll_wait(state->epfd,state->events,eventLoop->setsize,tvp ? (tvp->tv_sec* + tvp->tv_usec/) : -);
if (retval > )
{
int j; numevents = retval;
/*将满足条件的文件描述符和状态保存到fired中,后期逐个处理*/
for (j = ; j < numevents; j++)
{
int mask = ;
struct epoll_event *e = state->events+j; if (e->events & EPOLLIN) mask |= AE_READABLE;
if (e->events & EPOLLOUT) mask |= AE_WRITABLE;
if (e->events & EPOLLERR) mask |= AE_WRITABLE;
if (e->events & EPOLLHUP) mask |= AE_WRITABLE;
eventLoop->fired[j].fd = e->data.fd;
eventLoop->fired[j].mask = mask;
}
}
return numevents;
}

Redis事件管理(三)的更多相关文章

  1. Redis事件管理(二)

    Redis的定时器是自己实现的,不是很复杂.说说具体的实现吧. 定时器的存储维护采用的是普通的单向链表结构,具体节点定义为: /*时间定时器结构体*/ typedef struct aeTimeEve ...

  2. Redis事件管理(一)

    Redis统一的时间管理器,同时管理文件事件和定时器, 这个管理器的定义: #if defined(__APPLE__) #define HAVE_TASKINFO 1 #endif /* Test ...

  3. 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理

    服务器文档下载zip格式   刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...

  4. redis的管理工具

    phpredisadmin工具 rdbtools管理工具 saltstack管理redis 通过codis完成redis管理 一:phpredisadmin工具:类似于mysqladmin管理mysq ...

  5. 详解 Redis 内存管理机制和实现

    Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...

  6. zendframework 事件管理(一)

    zend里的事件管理器主要是为了实现: 1.观察者模式 2.面向切面设计 3.事件驱动构架 事件管理最基本的功能是将监听器与事件连接或断开.不论时连接还是断开都是通过shared collection ...

  7. Redis 内存管理与事件处理

    1 Redis内存管理 Redis内存管理相关文件为zmalloc.c/zmalloc.h,其只是对C中内存管理函数做了简单的封装,屏蔽了底层平台的差异,并增加了内存使用情况统计的功能. void * ...

  8. 安装window下的redis,redis可视化管理工具(Redis Desktop Manager)安装,基础使用,实例化项目

    以下包括内容: 一.redis下载安装,启动 二.Redis可视化管理工具(Redis Desktop Manager)安装 三.实例化项目 一.redis下载安装,启动 1,redis官方下载地址: ...

  9. redis : 桌面管理工具 redis-desktop-manager使用指南

    概要:一款好用的Redis桌面管理工具,支持命令控制台操作,以及常用,查询key,rename,delete等操作. 下载软件,请点击下面链接,进入下载页,选择对应版本: https://redisd ...

随机推荐

  1. Windows下如何修改php.ini的访问路径?

    Windows下,用 IIS跑PHP,有个缺点,那就是一定要把 php.ini 放在 Windows 的系统路径下 (C:/Windows) .不过,可以通过以下方式修改访问路径: 第一步: 把PHP ...

  2. 请求WebMethod, Ajax 处理更加专注

    在WebForm下 开发ajax程序,需要借助于一般处理程序(*.ashx)或web服务(*.asmx),并且每一个ajax请求,都要建一个这样的文件,如此一来,如 果在一个项目中ajax程序多了,势 ...

  3. apt-get 按照php7后apache 输出php源文件

    需要添加php7的模块 sudo apt-get install libapache2-mod-php7.0

  4. windows 下wamp环境1 配置之apache的安装

    一.安装apache2.4 打开网站 apachelounge.com    https://www.apachelounge.com/ 点击左侧Downloads,然后选择对应的版本,这里选择Apa ...

  5. 比较两个数据库表table结构不同之处

    /*--比较两个数据库的表字段差异 hy 适用多种版本库 --*/ /*--调用示例 exec p_comparestructure 'database1','database2' --*/ ) dr ...

  6. iOS开发——源代码管理——SVN

    一.源代码管理(svn)简介 01. 源代码管理工具概述 ======================================================================= ...

  7. RHEL/CentOS 7最小化安装后需做的30件事情

    导读 CentOS是一个工业标准的Linux发行版,是红帽企业版 Linux 的衍生版本.你安装完后马上就可以使用,但是为了更好地使用你的系统,你需要进行一些升级.安装新的软件包.配置特定服务和应用程 ...

  8. python文件头的#-*- coding: utf-8 -*- 的作用

    这一句其实是告诉编辑器,我的代码使用的格式是utf-8,如果没有这句编辑器就会自动去识别代码的文件格式,如果发现文件格式不是utf-8,就有可能去将编码格式转换为utf-8,比如本来是gbk的,编辑器 ...

  9. 跟着百度学PHP[4]OOP面对对象编程-12-对象接口技术(interface)

    PHP与大多数面向对象编程语言一样,不支持多重继承.也就是说每个类只能继承一个父类. 接口正是解决每个类只能继承一个父类这个问题的 接口用什么权限,继承的那个方法也要使用什么权限. 接口的声明使用:i ...

  10. MVPHelper

    在MVP的使用过程中,我们需要反复的去写各种MVP的接口和实现类, 实在是 太麻烦了!!所以抽时间撸了一款插件(只可用于Intellj IDEA 和 Android Studio),用于生成MVP接口 ...