之前总结了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底层框架的理解(五)的更多相关文章

  1. 对于redis底层框架的理解(一)

    近期学习了redis底层框架,好多东西之前都没听说过,算是大开眼界了. 先梳理下redis正常的通讯流程吧 首先服务器启动都有主函数main,这个main函数就在redis.c里 首先是initser ...

  2. 恋恋风辰 对于redis底层框架的理解(一)

    近期学习了redis底层框架,好多东西之前都没听说过,算是大开眼界了. 先梳理下redis正常的通讯流程吧 首先服务器启动都有主函数main,这个main函数就在redis.c里 首先是initser ...

  3. Redis底层数据结构详解

    上一篇说了Redis有五种数据类型,今天就来聊一下Redis底层的数据结构是什么样的.是这一周看了<redis设计与实现>一书,现来总结一下.(看书总是非常烦躁的!) Redis是由C语言 ...

  4. redis成长之路——(五)

    单例.哨兵.Cluster redis应用广泛,主要体现于实际场景的可用化,但是对于码农来说初步入手很多理念难以理解:码农的想法就是:为什么我要管那么多,我只想用,能用就行!所以必须将三个场景透明化. ...

  5. iOS10通知框架UserNotification理解与应用

    iOS10通知框架UserNotification理解与应用 一.引言 关于通知,无论与远程Push还是本地通知,以往的iOS系统暴漏给开发者的接口都是十分有限的,开发者只能对标题和内容进行简单的定义 ...

  6. Nginx Http框架的理解

    Nginx Http框架的理解 HTTP框架是Nginx基础框架的一部分,Nginx的其它底层框架如master-worker进程模型.event模块.mail 模块等. HTTP框架代码主要有2个模 ...

  7. Golang 网络爬虫框架gocolly/colly 五 获取动态数据

    Golang 网络爬虫框架gocolly/colly 五 获取动态数据 gcocolly+goquery可以非常好地抓取HTML页面中的数据,但碰到页面是由Javascript动态生成时,用goque ...

  8. 你可以这么理解五种I/O模型

    因为项目需要,接触和使用了Netty,Netty是高性能NIO通信框架,在业界拥有很好的口碑,但知其然不知其所以然. 所以本系列文章将从基础开始学起,深入细致的学习NIO.本文主要是介绍五种I/O模型 ...

  9. redis底层设计(一)——内部数据结构

    redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorted set ...

随机推荐

  1. 回归Qt——写在Qt5.10发布之日

    今天偶然看到一条关于Qt5.10发布的消息,发现Qt经历了诺基亚风波之后发展得依然良好,感到很欣慰.回头看上次关注Qt技术还是2011年,那时候用Qt4.7做一个小项目,对于一个写Win32界面和MF ...

  2. 初创型公司如何经济有效的申请邓白氏编码(DUNS)

    听说有免费,和800元,1500元,上万元等不同的申请方式?听说申请完还要等十数个工作日让邓白氏和苹果的数据库同步.不同高低价格的申请方式得到的编码都能被苹果接受吗? http://www.zhihu ...

  3. JS加密库

    作者声明:本博客中所写的文章,都是博主自学过程的笔记,参考了很多的学习资料,学习资料和笔记会注明出处,所有的内容都以交流学习为主.有不正确的地方,欢迎批评指正 本文主要是参考aicoder马伦老师的博 ...

  4. Python--matplotlib 绘图可视化练手--折线图/条形图

    最近学习matplotlib绘图可视化,感觉知识点比较多,边学习边记录. 对于数据可视化,个人建议Jupyter Notebook. 1.首先导包,设置环境 import pandas as pd i ...

  5. angularjs工作原理解析

    个人觉得,要很好的理解AngularJS的运行机制,才能尽可能避免掉到坑里面去.在这篇文章中,我将根据网上的资料和自己的理解对AngularJS的在启动后,每一步都做了些什么,做一个比较清楚详细的解析 ...

  6. 【dp】New Keyboard

    http://codeforces.com/gym/101397 B dp[i][j][k]: i为前一个行动的状态,0-switch.1-type,j为当前状态layout的编号,k 是已键入的字符 ...

  7. Nginx 配置站点

    1-进入 配置文件夹   cd /etc/nginx/cof.d   2-创建一个一站点名称命名的配置文件   vim kestrel-syslyracom.conf   3-在.conf 文件中输入 ...

  8. Java 异常注意事项

    异常的注意事项:   1,子类在覆盖父类方法时,父类的方法如果抛出了异常, 那么子类的方法只能抛出父类的异常或者该异常的子类.   2,如果父类抛出多个异常,那么子类只能抛出父类异常的子集.     ...

  9. 使用Kettle导出excel

    1.开发背景 在web项目中,经常会需要查询数据导出excel,以前比较常见的就是用poi.使用poi的时候也有两种方式,一种就是直接将集合一次性导出为excel,还有一种是分批次追加的方式适合数据量 ...

  10. jquery validate 一个注册表单的应用

    先看页面 前端表单代码  register.html <form class="mui-input-group" id="regForm"> < ...