RBL开发笔记三
2014-08-26 20:06:24
今天就是在开发这个EPOLL来处理网络事件 封装较为健壮的EPOLL模型来处理基本的网络IO
1) 超时这个主题先没有弄
在开发EPOLL包括select/poll类型io复用时,编程技术技巧分为几点:【下面都是针对与TCP协议 如果在以后开发中需要UDP会扩展这个编程技术】
1 要处理的文件描述符种类
a) listenfd=socket(); 这个listenfd 就是监听的listenfd 我们暂且把他作为一个总IO文件 其实这个listenfd就是一个数组索引。利用EPOLL监听的这个listenfd READBLE状态,那么这里肯定需要放一个TCPAcceptHandler的函数来做相应的操作 因为监听到相应的核心东东就是一系列raw的客户端传来的信息:
其中有 ip fd port 作为一个功能完善的程序 ip fd port 这些作为raw信息 外加一系列RBL服务端所要控制的信息 构造了RBLClient的这个重量级数据结构,这样网络层和RBL服务层能够通过这个数据结构进行结合了。TCPAcceptHandler在目前看来就是做这个事情。
b) 在a阶段构造了RBLClient 但是这个只是做了TCP的raw的ACCPET操作,但是需要引入真正的逻辑操作,也就是RBLServer接受到的所有的无论是自身的还是客户端的数据通信。 这里要利用typedef void FileProc(EpollEventLoop* ep,void *data,int fd) 给每一个来处理的文件的描述符注册一个通用的函数指针。这点内存消耗是必须的。这点暂时也不考虑了 这个阶段就是完成了注册事件。其实在这里需要处理可读和可写个事件 1) 可读是通过这层 交付给其他服务部分,2) 可写其他组建【自身】交给网络终端。
2 做成一个可以可随时插入的事件处理模型
在实现上要像REDIS一样,随时可以插入事件 比如建立一个EPOLLLOOP对象之后,在后面的N个步骤之后 咱们插入一个listenfd到EPOLLLOOP对象里。
在或者 我处理完一个客户端命令我需要告诉他该怎么做 也是通过回调事件来完成。 同时由于客户端随时挂掉或者主动离开 需要做DEL功能。 这些看起来是显而易见 但是需要仔细封装好。【在REDIS中是注入了readQueryFromClient/ sendReplyToClient这2个事件函数】所以呢 嘿嘿 面对这么优秀的REDIS设计 我还是利用的模式 不过在哪里潜入这2个函数呢? 需要仔细的体会体会哦
另外定义一个什么样的协议呢? 兼容REDIS 我采用同样的协议模式。
简单的类定义如下:
class EpollEventLoop
{
public:
EpollEventLoop(int maxclient_):maxclient(maxclient_),maxepollevent(maxclient_),maxfd(-1)
{
epollfd=epoll_create(2048);
if(epollfd==-1)
std::cout<<"epoll create failed!"<<std::endl;
}
void CreatFileEvent(int fd,FileEvent* prere_event); //这里其实是注册事件
void DeleteFileEvent(int fd,int mask); //这里是删除事件
void ProcessEvents(int flag);//flag代表是那种类型的事件 在这里就是读写事件
~EpollEventLoop()
{
}
private:
int maxfd; //当前注册最大文件数目 eventloop初始化为-1
std::vector<FileEvent> fileevent; //文件事件 用std::vector存储
int epollfd; //epollfd文件描述符
std::vector<struct epoll_event> maxepollevent;
int maxclient;
};
REDIS协议实现起来比较繁琐的是批处理操作:
*<参数数量> CR LF
$<参数 1 的字节数量> CR LF
<参数 1 的数据> CR LF
...
$<参数 N 的字节数量> CR LF
<参数 N 的数据> CR LF
这样看来:传入上面总结的3个function(readQueryFromClient/ sendReplyToClient/TCPAcceptHandler)上都是以RBLClient做为主参数,解码或者加码都是在readQueryFromClient/ sendReplyToClient函数完成。
实现上还有一个难点:就是加码或者解码时这边传入的数据缓冲区不够怎么办?不能一下子放到结构化数据中,那就在实现时 做一个标记位,分多次读完 这样确实麻烦 这样在RBLClient就要多加几个结构来控制这些量了。 快哭了 网络协议部分http://www.redisdoc.com/en/latest/topic/protocol.html 就参考这个了 简化它 毕竟没有REDIS命令那么多 接下来是一个头痛的问题:上面的实现版本是单线程模式:
接下来该怎么实现一个多线程呢?
EPOLL线程:加入任务队列WorkQueue中, 是把什么加入到这个WorkQueue中呢? 其实就是把一个个RBLClient副本到WorkQueue中,而消费线程也就是调用TakeQueue()
形式化:
LOCK1()
TakeQUEUE()
UNLOCK1()
……
……
LOCK2()
CommandExecute()
UNLOCK2()
对于LOCK1部分的实现 用无锁队列
对于LOCK2 这里实现有一个CommandExecute() 这里就是控制一个部分bit数组 所以对我来讲 这个地方如果采用spin_lock() 加锁会不会好一一些呢? 这个需要评估
另外而言: 对于一致性而言,这样的操作模式 对于单客户可能不会马上得到想要的结果 这是一种必须的 是需要一个时间窗口 并非强一致性 我这里是牺牲了强一致性的 但是如果WorkQueue一直非常小的话 这个时间窗口肯定就非常小了 对应用程序造不成很大的影响。
明天的实现部分估计就是这个最难熬的线程控制部分了 这个部分计划用2到3天完成。明天把EventLoop代码实现的部分和协议实现部分先贴出来 然后串讲下思路
先这样了 bye
RBL开发笔记三的更多相关文章
- Django开发笔记三
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.基于类的方式重写登录:views.py: from ...
- RBL开发笔记一
从这个系列开始 陆续记录整个RBL开发的过程 废话不多说 直入主题 10:54:53 2014-08-25 今天开发任务: RBL.h 的框架搭建出来 包括RBLServer RB ...
- RBL开发笔记二
17:13:55 2014-08-25 有以下几个点: 第一 :怎么在预处理阶段能够做到识别某个宏是否给定义了 这里就定义了一个SystemConfig.h 专门做这个事情 当然是需要make ...
- Vue-cli开发笔记三----------引入外部插件
(一)绝对路径直接引入: (1)主入口页面index.html中头部script标签引入: <script type="text/javascript" src=" ...
- 钉钉开发笔记(三)MySQL的配置
最近在编写web的过程中,经常需要与后台工作人员互动.由于比较麻烦.没有效率. 就果断的请教了,公司的后台大牛,学习下数据库的一些简单操作,现在就把利用MySQL连接服务器, 进行可视化操作的简单步骤 ...
- openwrt开发笔记三:uci移植及API调用
1.uci编译安装.移植 安装依赖 libubox #安装cmake sudo apt-get install cmake #下载依赖库libubox git clone http://git.nbd ...
- Django开发笔记六
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.登录功能完善 登录成功应该是重定向到首页,而不是转发 ...
- Django开发笔记五
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.页面继承 定义base.html: <!DOC ...
- Django开发笔记四
Django开发笔记一 Django开发笔记二 Django开发笔记三 Django开发笔记四 Django开发笔记五 Django开发笔记六 1.邮箱激活 users app下,models.py: ...
随机推荐
- 我的android学习经历32
android系统架构 1.Linux内核层(LINUX KERNEL) 这是系统架构的最低层,这层为android设备的硬件提供了驱动 2.系统运行库层(LIBRARIES) 这一层为倒数第二层,利 ...
- 第四章· ucos系统及其任务
来自为知笔记(Wiz)
- centos7 gitlab
yum -y update chmod +x /etc/rc.d/rc.local vi /etc/selinux/config SELINUX=disabled reboot vi /etc/hos ...
- UiAutomator环境搭建及详细操作
一.环境搭建 1.1 必备条件 JDK SDK(API高于15) Eclipse(安装ADT插件) ANT(用于编译生成的jar) 安装JDK并添加环境变量 1.2 详细步骤 1.安装JDK并添加环境 ...
- 关于NOR-FLASH和NAND-fLASH的区别。——Arvin
NANDFLASH: Nand-flash内存是flash内存的一种,1989年,东芝公司发表了NAND flash结构.其内部采用非线性宏单元模式,为固态大容量内存的实现提供了廉价有效的解决方案.N ...
- Head First 设计模式 --3 装饰者模式 开闭原则
装饰者模式:动态的将责任附加到对象上,若要扩展功能,装饰者提供了比集成更有弹性的替代方案.设计原则:1:封装变化2:多用组合,少用继承3:针对接口编程,不针对实现编程4:为对象之间的松耦合设计而努力5 ...
- MFC List Control 控件添加单元格编辑,实现可编辑重写
在实现随机生成四则运算的个人项目中,目前已经完成基本功能,想要把程序变成一个Windows界面的程序.原本以为学习过MFC,应该很快就能完成.但是由于以前用的都是VC6.0,这次用了VS2010,稍微 ...
- 【必备】史上最全的浏览器 CSS & JS Hack 手册(转)
浏览器渲染页面的方式各不相同,甚至同一浏览器的不同版本(“杰出代表”是 IE)也有差异.因此,浏览器兼容成为前端开发人员的必备技能.如果有一份浏览器 Hack 手册,那查询起来就方便多了.这篇文章就向 ...
- solr windows 启动和关闭命令
进入bin目录执行 启动:solr -e dih 停止:solr stop -all D:\Solr\solr-5.2.1\solr-5.2.1\bin>solr -e dih
- python讲一个列表写入excel表中
连接为http://blog.csdn.net/a491057947/article/details/47614263 http://www.crifan.com/export_data_to_exc ...