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. Window环境下搭建MyEclipse+Tomcat+MAVEN+SVN

    1.JDK的安装 首先下载JDK,这个从sun公司官网(http://www.oracle.com/)可以下载,根据自己的系统选择64位还是32位,安装过程就是next一路到底.安装完成之后当然要配置 ...

  2. git之远程标签下载(远程分支)

    一般我们发布一个新版本到线上服务器时都会在版本库中打一个标签,这样我们可以随时查看这个打标签的版本,就是说标签其实是版本库中一个快照.git的标签与分支类似,区别是分支是可变的而标签是不可变.接下来我 ...

  3. git之remote repository create(远程仓库创建)

    参考:Git教程 - 廖雪峰的官方网站 1.在Git bash窗口执行如下指令创建SSH KEY: ssh-keygen -t rsa -C "sunjf@biomarker.com.cn& ...

  4. FineUI第十二天---锚点布局

    锚点布局的典型结构: <x:Panel Layout="Anchor" runat="server">              <Items ...

  5. Linux中获取本机网络信息的几个函数及应用

    一.读取/etc/hosts 几个函数 头文件<netdb.h> 1.void sethostent(int stayopen);//开打/etc/hosts 配置文件 2.struct ...

  6. Joda-time是java处理时间非常棒的jar

    http://www.joda.org/joda-time/ maven: <dependency> <groupId>joda-time</groupId> &l ...

  7. leetcode 82. Remove Duplicates from Sorted List II

    Given a sorted linked list, delete all nodes that have duplicate numbers, leaving only distinct numb ...

  8. spring 部分配置内容备忘

    1.spring定时器简单配置: <bean name="taskJob" class="com.netcloud.mail.util.TaskJob"& ...

  9. linux kernel 杂谈

    首先介绍一下背景吧,工作三个星期了.复习了一波u-boot,跟了一下事件上报,搞了下平台设备,扣了一个内存检查代码. 想想生活是不是有点无聊.对啊,真的很无聊!!!! 无聊也没有办法啊,所以找点方法去 ...

  10. 关于mysql安全

    修改root用户密码: update mysql.user set password=password('new_passwd') where user='root'; flush privilege ...