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 ...
随机推荐
- 自定义C/C++头文件以及头文件重复定义解决
今天再看二叉树的知识,看着看着就看到C/C++的头文件及头文件重复定义这一块去了.以前就看到过这个问题,但是自己一直没有用到这方面的东西,今天遇到就顺便总结一下,等以后忘了再回来看看. 首先明确一点C ...
- InnoDB锁机制分析
InnoDB锁机制常常困扰大家,不同的条件下往往表现出不同的锁竞争,在实际工作中经常要分析各种锁超时.死锁的问题.本文通过不同条件下的实验,利用InnoDB系统给出的各种信息,分析了锁的工作机制.通过 ...
- 用jQuery实现的一种网页内容呈现方式
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...
- DEV控件GridControl常用属性设置
1. 如何解决单击记录整行选中的问题 View->OptionsBehavior->EditorShowMode 设置为:Click 2. 如何新增一条记录 (1).gridView.Ad ...
- 如何在IE8设置透明背景
background:rgba(0,0,0,0.5);filter: progid:DXImageTransform.Microsoft.gradient(startcolorstr=#7F00000 ...
- android socket编程用Bufferreader读取的一个失败教训
由于我的手机需要用笔记本开的wifi,躺在床上玩手机时需要关电脑或者是要让电脑放歌的时候总是不想下床,于是我想能不能用一个APP,然后通过局域网实现在手机上对电脑进行操控呢?说干就干. 我在电脑上用的 ...
- Unity手游之路<三> 基于Unity+Java的聊天室源码
http://blog.csdn.net/janeky/article/details/17233199 项目介绍 这是一个简单的Unity项目,实现最基本的聊天室群聊功能.登录聊天室后,用户可以输入 ...
- Longest Common Subsequence
Given two strings, find the longest common subsequence (LCS). Your code should return the length of ...
- HTTP头部详解
因为之后的HTTP头注入要学习这些所以就看了.觉得很不错,算是学习前的科普. <HTTP头部详解>转载自:http://www.cnblogs.com/lcamry/p/5763040.h ...
- Sqli-LABS通关笔录-14
这一节让我学习到了 1.extractvalue函数(该函数用于对xml文件进行查询和修改,于此相关的还有一个叫“updatexml”函数) 语法:extractvalue(XML_document, ...