对于redis底层框架的理解(五)
之前总结了redis的通讯流程,基本框架,epoll的封装等等,这次介绍下
redis对于select模型的封装
//select 模型
typedef struct aeApiState {
//读文件描述符集合,写文件描述符集合
fd_set rfds, wfds;
/* We need to have a copy of the fd sets as it's not safe to reuse
* FD sets after select(). */
//读写集合的副本
fd_set _rfds, _wfds;
} aeApiState;
_rfds和_wfds是读写结合的副本,因为select调用后会将读写集合中未就绪的文件描述符
清除,所以每次用_rfds和_wfds传入,就不用担心原读写集合描述符被清除。
封装的基于select的初始化函数
static int aeApiCreate(aeEventLoop *eventLoop) {
//开辟aeApiState空间
aeApiState *state = zmalloc(sizeof(aeApiState));
if (!state) return -;
//读写集合清零
FD_ZERO(&state->rfds);
FD_ZERO(&state->wfds);
eventLoop->apidata = state;
return ;
}
函数将读写集合清零,并且将state回传给eventloop的apidata部分。
内存回收功能
//释放空间
static void aeApiFree(aeEventLoop *eventLoop) {
zfree(eventLoop->apidata);
}
封装的添加和删除事件
//select 添加事件
static int aeApiAddEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata; if (mask & AE_READABLE) FD_SET(fd,&state->rfds);
if (mask & AE_WRITABLE) FD_SET(fd,&state->wfds);
return ;
} //select 删除事件
static void aeApiDelEvent(aeEventLoop *eventLoop, int fd, int mask) {
aeApiState *state = eventLoop->apidata; if (mask & AE_READABLE) FD_CLR(fd,&state->rfds);
if (mask & AE_WRITABLE) FD_CLR(fd,&state->wfds);
}
添加事件函数将文件描述根据mask是读事件还是写事件放入不同的set
删除事件根据文件描述符mask是读事件还是写事件从不同的set中清除
下面是核心功能,事件派发
//select 触发事件
static int aeApiPoll(aeEventLoop *eventLoop, struct timeval *tvp) {
aeApiState *state = eventLoop->apidata;
int retval, j, numevents = ;
//将select读集合的数据拷贝到_rfds
memcpy(&state->_rfds,&state->rfds,sizeof(fd_set));
//将select写集合数据拷贝到_wfds
memcpy(&state->_wfds,&state->wfds,sizeof(fd_set)); //从读和写的copy集合里选出就绪的文件描述符
retval = select(eventLoop->maxfd+,
&state->_rfds,&state->_wfds,NULL,tvp); //大于零表示有就绪的文件描述符 if (retval > ) {
//select的弊端所在,每次都要将所有的文件描述符轮询一遍
for (j = ; j <= eventLoop->maxfd; j++) { int mask = ;
aeFileEvent *fe = &eventLoop->events[j]; if (fe->mask == AE_NONE) continue;
//aeFileEvent 事件可读
if (fe->mask & AE_READABLE && FD_ISSET(j,&state->_rfds))
mask |= AE_READABLE; //aeFileEvent 事件可写
if (fe->mask & AE_WRITABLE && FD_ISSET(j,&state->_wfds))
mask |= AE_WRITABLE;
eventLoop->fired[numevents].fd = j;
eventLoop->fired[numevents].mask = mask;
numevents++;
}
}
return numevents;
}
先将读写集合中的内容copy的_rfds和_wfds中,分别传入select函数中,
这样select后返回的_rfds中只有就绪的读socket
_wfds中只有就绪的写socket
通过FD_ISSET判断读写事件之后放到eventloop的fire队列里。
基本的封装就是这个样子,select模型相对容易理解
我的公众号:

对于redis底层框架的理解(五)的更多相关文章
- 对于redis底层框架的理解(一)
近期学习了redis底层框架,好多东西之前都没听说过,算是大开眼界了. 先梳理下redis正常的通讯流程吧 首先服务器启动都有主函数main,这个main函数就在redis.c里 首先是initser ...
- 恋恋风辰 对于redis底层框架的理解(一)
近期学习了redis底层框架,好多东西之前都没听说过,算是大开眼界了. 先梳理下redis正常的通讯流程吧 首先服务器启动都有主函数main,这个main函数就在redis.c里 首先是initser ...
- Redis底层数据结构详解
上一篇说了Redis有五种数据类型,今天就来聊一下Redis底层的数据结构是什么样的.是这一周看了<redis设计与实现>一书,现来总结一下.(看书总是非常烦躁的!) Redis是由C语言 ...
- redis成长之路——(五)
单例.哨兵.Cluster redis应用广泛,主要体现于实际场景的可用化,但是对于码农来说初步入手很多理念难以理解:码农的想法就是:为什么我要管那么多,我只想用,能用就行!所以必须将三个场景透明化. ...
- iOS10通知框架UserNotification理解与应用
iOS10通知框架UserNotification理解与应用 一.引言 关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义 ...
- Nginx Http框架的理解
Nginx Http框架的理解 HTTP框架是Nginx基础框架的一部分,Nginx的其它底层框架如master-worker进程模型.event模块.mail 模块等. HTTP框架代码主要有2个模 ...
- Golang 网络爬虫框架gocolly/colly 五 获取动态数据
Golang 网络爬虫框架gocolly/colly 五 获取动态数据 gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goque ...
- 你可以这么理解五种I/O模型
因为项目需要,接触和使用了Netty,Netty是高性能NIO通信框架,在业界拥有很好的口碑,但知其然不知其所以然. 所以本系列文章将从基础开始学起,深入细致的学习NIO.本文主要是介绍五种I/O模型 ...
- redis底层设计(一)——内部数据结构
redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...
随机推荐
- RyuBook1.0案例三:REST Linkage
REST Linkage 该小结主要介绍如何添加一个REST Link 函数 RYU本身提供了一个类似WSGI的web服务器功能.借助这个功能,我们可以创建一个REST API. 基于创建的REST ...
- 电脑提示‘您需要来自Administration的权限才能对此文件夹进行更改’怎么删除文件
电脑提示'您需要来自Administration的权限才能对此文件夹进行更改'怎么删除文件 应该怎么做 win7系统需要定期删除一些无用的文件,扩大内存空间,但是在删除文件的时候弹出提示"您 ...
- Leetcode_2. Add_Two_Number
2. Add_Two_Number 用两个非空链表分别表示两个非负整数,链表的节点表示数字的位,链表头表示数字的低位,链表尾表示数字高位.求两个链表所表示数字的和. 比如: Input: (2 -&g ...
- scrum立会报告+燃尽图(第三周第二次)
此作业要求参见:https://edu.cnblogs.com/campus/nenu/2018fall/homework/2284 项目地址:https://coding.net/u/wuyy694 ...
- 404 Note Found队——现场编程
目录 组员职责分工 github 的提交日志截图 程序运行截图 程序运行环境 GUI界面 基础功能实现 运行视频 LCG算法 过滤(降权)算法 算法思路 红黑树 附加功能一 背景 实现 附加功能二(迭 ...
- 周总结<1>
由于都不清楚周总结的格式,所以就没有写了.不过,上次听了老师的课,觉得应该要好好写写了,至少今后可以明白自己有做过什么事情,至少不会觉得自己在各个方面没有收获.不过,可能没有按照格式来写.希望老师体谅 ...
- 利用canvas对上传图片进行上传前压缩
利用谷歌调式工具发现,图片大小直接影响着首屏加载时间. 且考虑到后期服务端压力,图片压缩特别必要. 本文是前端利用canvas实现图片.参考文章:https://www.cnblogs.com/007 ...
- PHP中类型约束
类型约束 什么叫类型约束? 就是要求某个变量只能使用(接收,存储)某种指定的数据类型: php属于“弱类型语言”,通常不支持类型约束: 相应的,强类型语言,类型约束却是其“基本特征”. php中,只支 ...
- struts.xml 文件中的 namespace 属性图文详解
namespace:名称空间.默认值是""(空字符串). 名称空间+动作名称:构成了动作的访问路径
- bzoj1923[Sdoi2010]外星千足虫(高斯消元)
Description Input 第一行是两个正整数 N, M. 接下来 M行,按顺序给出 Charles 这M次使用“点足机”的统计结果.每行 包含一个“01”串和一个数字,用一个空格隔开.“01 ...