Redis事件管理(三)
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事件管理(三)的更多相关文章
- Redis事件管理(二)
Redis的定时器是自己实现的,不是很复杂.说说具体的实现吧. 定时器的存储维护采用的是普通的单向链表结构,具体节点定义为: /*时间定时器结构体*/ typedef struct aeTimeEve ...
- Redis事件管理(一)
Redis统一的时间管理器,同时管理文件事件和定时器, 这个管理器的定义: #if defined(__APPLE__) #define HAVE_TASKINFO 1 #endif /* Test ...
- 服务器文档下载zip格式 SQL Server SQL分页查询 C#过滤html标签 EF 延时加载与死锁 在JS方法中返回多个值的三种方法(转载) IEnumerable,ICollection,IList接口问题 不吹不擂,你想要的Python面试都在这里了【315+道题】 基于mvc三层架构和ajax技术实现最简单的文件上传 事件管理
服务器文档下载zip格式 刚好这次项目中遇到了这个东西,就来弄一下,挺简单的,但是前台调用的时候弄错了,浪费了大半天的时间,本人也是菜鸟一枚.开始吧.(MVC的) @using Rattan.Co ...
- redis的管理工具
phpredisadmin工具 rdbtools管理工具 saltstack管理redis 通过codis完成redis管理 一:phpredisadmin工具:类似于mysqladmin管理mysq ...
- 详解 Redis 内存管理机制和实现
Redis是一个基于内存的键值数据库,其内存管理是非常重要的.本文内存管理的内容包括:过期键的懒性删除和过期删除以及内存溢出控制策略. 最大内存限制 Redis使用 maxmemory 参数限制最大可 ...
- zendframework 事件管理(一)
zend里的事件管理器主要是为了实现: 1.观察者模式 2.面向切面设计 3.事件驱动构架 事件管理最基本的功能是将监听器与事件连接或断开.不论时连接还是断开都是通过shared collection ...
- Redis 内存管理与事件处理
1 Redis内存管理 Redis内存管理相关文件为zmalloc.c/zmalloc.h,其只是对C中内存管理函数做了简单的封装,屏蔽了底层平台的差异,并增加了内存使用情况统计的功能. void * ...
- 安装window下的redis,redis可视化管理工具(Redis Desktop Manager)安装,基础使用,实例化项目
以下包括内容: 一.redis下载安装,启动 二.Redis可视化管理工具(Redis Desktop Manager)安装 三.实例化项目 一.redis下载安装,启动 1,redis官方下载地址: ...
- redis : 桌面管理工具 redis-desktop-manager使用指南
概要:一款好用的Redis桌面管理工具,支持命令控制台操作,以及常用,查询key,rename,delete等操作. 下载软件,请点击下面链接,进入下载页,选择对应版本: https://redisd ...
随机推荐
- 【血的教训】玩 Ubuntu 遇到的致命问题(进不了系统)及 解决方案
[问题1] 按照文章“U盘安装Windows 7 + Ubuntu 14 双系统笔记”在 Windows 7 基础上安装了 Ubuntu 14 系统,实现双系统切换,某一天, 通过如下命令行 sudo ...
- 解决 Mac Pro 用 Excel 打开 CSV 文件不能正常显示的问题
在做系统后台的时候,往往会有导出系统信息(如,用户信息)功能,一般导出为CSV文件. 先前在 Windows 下,导出的CSV文件用 Excel 打开能正常显示,可现在在 Mac 系统中,显示一团乱, ...
- 线程7-ThreadLocal
有时间再整理 ThreadLocal不是用来解决对象共享访问问题的,而主要是提供了保持对象的方法和避免参数传递的方便的对象访问方式.归纳了两点: 1.每个线程中都有一个自己的ThreadLocalMa ...
- java之google style
Google的Java编码规范英文版: http://google-styleguide.googlecode.com/svn/trunk/javaguide.html Google的Java编码规范 ...
- C#网络爬虫 WebUtility使用 转义字符 urlCode
背景: 在C#写网络爬虫时候,有时候需要将html中的转义字符进行处理,还有网址中的中文处理 一.html转义字符处理 1.ASP.NET中的html解析 HttpUtility.HtmlDecode ...
- 08OC之Foundation框架
1.Foundation框架简述 在前面,我们创建一个类的时候,都会选择Cocoa Class.到底Cocoa Class是什么东西呢? Cocoa 不是一门编程语言,因为它可以运行在多种编程语言上, ...
- scoll滚动
[前端性能]高性能滚动 scroll 及页面渲染优化 最近在研究页面渲染及web动画的性能问题,以及拜读<CSS SECRET>(CSS揭秘)这本大作. 本文主要想谈谈页面优化之滚动优 ...
- 【原创】ReFlux细说
ReFlux细说 Flux作为一种应用架构(application architecture)或是设计模式(pattern),阐述的是单向数据流(a unidirectional data flow) ...
- OLA音频变速算法的仿真与剖析
前段时间,在尝试音乐节拍数的提取时,终于有了突破性的进展,效果基本上比市面上的许多商业软件还要好,在作节拍数检测时,高频信息作用不大, 通过重采样减小运算量.重采样让我想起了在学校里面做的变速变调算法 ...
- phpcms调用某个栏目下的所有二级栏目
在html中直接这样调用就可以了,subcat中的值为父栏目的catid {loop subcat(93) $r}{/loop} 注意subcat方法的参数,如果只写一个参数,也就是父栏目id,那该父 ...